不能在 actionlistener 的 JFrame 上使用 add 方法
Cannot use add method on JFrame in actionlistener
我正在做一个学校项目,但我被卡住了。单击 JMenuItem 后,我试图在侦听器中创建面板(在 JFrame 上简单添加方法),但它不起作用。如果我尝试在侦听器外部创建面板,它在 no.bud 内部工作得很好。 Panel 只是 JPanel 的扩展,目前没有任何功能,但将来计划在其中添加一些功能。
public class Gui implements GuiConstants, ActionListener {
public static final int INIT_WIDTH = 1024;
public static final int INIT_HEIGHT = 560;
private JFrame frame;
private KPanel KPanels[];
private GridBagConstraints gbc;
public Gui() {
KPanels = new KPanel[4];
this.gbc = new GridBagConstraints();
}
/**
* Vytváří okno aplikace + inicializuje toolbar
*/
public void createWindow() {
frame = new JFrame(Strings.get("window-title"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle(Strings.get("window-title"));
frame.setJMenuBar(new KToolbar());
frame.pack();
frame.setSize(Gui.INIT_WIDTH, Gui.INIT_HEIGHT);
frame.setVisible(true);
frame.setLayout(new GridBagLayout());
addToolbarListener(this);
createPanel(1);
}
/**
* Nastaví listener pro toolbar akce (kliknutí)
* @param listener
*/
public void addToolbarListener(ActionListener listener) {
((KToolbar) frame.getJMenuBar()).addActionListener(listener);
}
public void disableToolbarItem(int itemId) {
((KToolbar) frame.getJMenuBar()).disable(itemId);
}
public KPanel createPanel(int i) {
return this.createPanel(i, null);
}
/**
* Vytvoří i-tý panel v případě, že ještě neexistuje a i je v rozsahu 0-3 včetně
* @param i
* @return
*/
public KPanel createPanel(int i, Color color){
if (i > 3 || i < 0 || KPanels[i] != null) {
return null;
}
this.KPanels[i] = new KPanel();
if (color != null)
this.KPanels[i].setBackground(color);
this.gbc.fill = GridBagConstraints.BOTH;
this.gbc.weightx = 1;
this.gbc.weighty = 1;
this.gbc.gridx = i % 2;
this.gbc.gridy = i / 2;
this.frame.add(this.KPanels[i], this.gbc);
return this.KPanels[i];
}
/**
* Odstraní t-tý panel v případě, že existuje a i je v rozsahu 0-3 včetně.
* @param i
* @return
*/
public boolean removePanel(int i) {
if (i > 3 || i < 0 || KPanels[i] == null) {
return false;
}
this.frame.remove(this.KPanels[i]);
this.KPanels[i] = null;
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
createPanel(2, Color.CYAN);
}
}
public class KMenuItem extends JMenuItem {
private int id;
KMenuItem(String name, int id) {
super(name);
this.id = id;
}
public int getId() {
return id;
}
}
public class KToolbar extends JMenuBar{
ArrayList<KMenuItem> KMenuItems;
KToolbar() {
super();
KMenuItems = new ArrayList<>();
generateMenu();
}
public void addActionListener(ActionListener listener) {
for (KMenuItem item : KMenuItems) {
item.addActionListener(listener);
}
}
public void disable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(false);
}
}
public void enable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(true);
}
}
private KMenuItem getLast() {
return KMenuItems.get(KMenuItems.size() - 1);
}
private void generateMenu() {
JMenu game = new JMenu(Strings.get("game"));
KMenuItems.add(new KMenuItem(Strings.get("button-exit"), Gui.EXIT));
game.add(getLast());
JMenu newGame = new JMenu(Strings.get("button-new-game"));
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-current"), Gui.NEW_GAME_CURRENT));
newGame.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-panel"), Gui.NEW_GAME_PANEL));
newGame.add(getLast());
game.add(newGame);
KMenuItems.add(new KMenuItem(Strings.get("button-save"), Gui.SAVE));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-load"), Gui.LOAD));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-abort-game"), Gui.ABORT_GAME));
game.add(getLast());
add(game);
}
}
public class KPanel extends JPanel {
}
public interface GuiConstants {
// System
public static final int EXIT = 1;
public static final int SAVE = 2;
public static final int LOAD = 3;
// Language
public static final int CHANGE_LANG = 4;
// Game
public static final int NEW_GAME_PANEL = 5;
public static final int NEW_GAME_CURRENT = 6;
public static final int UNDO_GAME = 7;
public static final int REDO_GAME = 8;
public static final int ABORT_GAME = 9;
public static final int HINT_GAME = 10;
}
public class Main {
private Gui GUI;
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Main();
}
});
}
Main() {
GUI = new Gui();
GUI.createWindow();
}
}
编辑:添加了完整示例。没有错误日志。我什至检查了对象引用,一切都合适。它只是不会以某种方式添加到框架中,我不知道为什么。
我自己解决了。我忘了用每个 frame.add 调用 frame.revalidate() (在 createPanel 方法中)。
我正在做一个学校项目,但我被卡住了。单击 JMenuItem 后,我试图在侦听器中创建面板(在 JFrame 上简单添加方法),但它不起作用。如果我尝试在侦听器外部创建面板,它在 no.bud 内部工作得很好。 Panel 只是 JPanel 的扩展,目前没有任何功能,但将来计划在其中添加一些功能。
public class Gui implements GuiConstants, ActionListener {
public static final int INIT_WIDTH = 1024;
public static final int INIT_HEIGHT = 560;
private JFrame frame;
private KPanel KPanels[];
private GridBagConstraints gbc;
public Gui() {
KPanels = new KPanel[4];
this.gbc = new GridBagConstraints();
}
/**
* Vytváří okno aplikace + inicializuje toolbar
*/
public void createWindow() {
frame = new JFrame(Strings.get("window-title"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle(Strings.get("window-title"));
frame.setJMenuBar(new KToolbar());
frame.pack();
frame.setSize(Gui.INIT_WIDTH, Gui.INIT_HEIGHT);
frame.setVisible(true);
frame.setLayout(new GridBagLayout());
addToolbarListener(this);
createPanel(1);
}
/**
* Nastaví listener pro toolbar akce (kliknutí)
* @param listener
*/
public void addToolbarListener(ActionListener listener) {
((KToolbar) frame.getJMenuBar()).addActionListener(listener);
}
public void disableToolbarItem(int itemId) {
((KToolbar) frame.getJMenuBar()).disable(itemId);
}
public KPanel createPanel(int i) {
return this.createPanel(i, null);
}
/**
* Vytvoří i-tý panel v případě, že ještě neexistuje a i je v rozsahu 0-3 včetně
* @param i
* @return
*/
public KPanel createPanel(int i, Color color){
if (i > 3 || i < 0 || KPanels[i] != null) {
return null;
}
this.KPanels[i] = new KPanel();
if (color != null)
this.KPanels[i].setBackground(color);
this.gbc.fill = GridBagConstraints.BOTH;
this.gbc.weightx = 1;
this.gbc.weighty = 1;
this.gbc.gridx = i % 2;
this.gbc.gridy = i / 2;
this.frame.add(this.KPanels[i], this.gbc);
return this.KPanels[i];
}
/**
* Odstraní t-tý panel v případě, že existuje a i je v rozsahu 0-3 včetně.
* @param i
* @return
*/
public boolean removePanel(int i) {
if (i > 3 || i < 0 || KPanels[i] == null) {
return false;
}
this.frame.remove(this.KPanels[i]);
this.KPanels[i] = null;
return true;
}
@Override
public void actionPerformed(ActionEvent e) {
createPanel(2, Color.CYAN);
}
}
public class KMenuItem extends JMenuItem {
private int id;
KMenuItem(String name, int id) {
super(name);
this.id = id;
}
public int getId() {
return id;
}
}
public class KToolbar extends JMenuBar{
ArrayList<KMenuItem> KMenuItems;
KToolbar() {
super();
KMenuItems = new ArrayList<>();
generateMenu();
}
public void addActionListener(ActionListener listener) {
for (KMenuItem item : KMenuItems) {
item.addActionListener(listener);
}
}
public void disable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(false);
}
}
public void enable(int id) {
for (KMenuItem mi : KMenuItems) {
if (mi.getId() == id)
mi.setEnabled(true);
}
}
private KMenuItem getLast() {
return KMenuItems.get(KMenuItems.size() - 1);
}
private void generateMenu() {
JMenu game = new JMenu(Strings.get("game"));
KMenuItems.add(new KMenuItem(Strings.get("button-exit"), Gui.EXIT));
game.add(getLast());
JMenu newGame = new JMenu(Strings.get("button-new-game"));
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-current"), Gui.NEW_GAME_CURRENT));
newGame.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-new-game-panel"), Gui.NEW_GAME_PANEL));
newGame.add(getLast());
game.add(newGame);
KMenuItems.add(new KMenuItem(Strings.get("button-save"), Gui.SAVE));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-load"), Gui.LOAD));
game.add(getLast());
KMenuItems.add(new KMenuItem(Strings.get("button-abort-game"), Gui.ABORT_GAME));
game.add(getLast());
add(game);
}
}
public class KPanel extends JPanel {
}
public interface GuiConstants {
// System
public static final int EXIT = 1;
public static final int SAVE = 2;
public static final int LOAD = 3;
// Language
public static final int CHANGE_LANG = 4;
// Game
public static final int NEW_GAME_PANEL = 5;
public static final int NEW_GAME_CURRENT = 6;
public static final int UNDO_GAME = 7;
public static final int REDO_GAME = 8;
public static final int ABORT_GAME = 9;
public static final int HINT_GAME = 10;
}
public class Main {
private Gui GUI;
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Main();
}
});
}
Main() {
GUI = new Gui();
GUI.createWindow();
}
}
编辑:添加了完整示例。没有错误日志。我什至检查了对象引用,一切都合适。它只是不会以某种方式添加到框架中,我不知道为什么。
我自己解决了。我忘了用每个 frame.add 调用 frame.revalidate() (在 createPanel 方法中)。