【问题标题】:Cannot use add method on JFrame in actionlistener [duplicate]无法在 actionlistener 中的 JFrame 上使用 add 方法 [重复]
【发布时间】:2017-05-04 10:45:34
【问题描述】:

我正在做一个学校项目,但我被困住了。单击 JMenuItem 后,我试图在侦听器中创建一个面板(在 JFrame 上简单添加方法),但它不起作用。如果我尝试在侦听器之外创建面板,它在没有的情况下工作得很好。 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();
    }
}

编辑:添加了完整的示例。没有错误日志。我什至检查了对象引用,一切都合适。它只是不以某种方式添加到框架中,我不知道为什么。

【问题讨论】:

  • 类型不应该是JMenuItem,而不是MenuItem吗?
  • 不,它的扩展。 MenuItem 扩展了 JMenuItem
  • 还有JToolBar,不是ToolBar,还有JPanel,不是Panel?您似乎在随意混合 AWT 和 Swing。
  • Toolbar 和 Panel 和 MenuItem 是我的类,因为我需要向它们添加额外的方法
  • 考虑重新命名您的类,以免它们与其他核心 Java 类发生冲突。为了最好地回答您的问题,您需要创建并发布 minimal reproducible example,以便我们能够亲身体验您的问题并发布完整的错误消息。

标签: java swing jframe add actionlistener


【解决方案1】:

我自己解决了。我忘了用每个 frame.add 调用 frame.revalidate()(在 createPanel 方法中)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-29
    • 2016-01-17
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 1970-01-01
    相关资源
    最近更新 更多