难以从Jpanel中删除所有组件

时间:2009-02-22 07:00:28

标签: java swing components jpanel

G'day all,

我正在编写项目的主菜单。菜单显示正常。我还为菜单上的三个按钮设置了ActionListeners。

我想要做的是当用户选择“开始新游戏”时,将JPanel重新用于一组新的单选按钮。

然而,编写ActionPerformed以从JPanel中删除现有组件让我感到难过。我知道removeAll在某种程度上很重要,但遗憾的是NetBeans告诉我,我无法在ActionPerformed中的mainMenu JPanel对象上调用它。所以我在下面的代码中对它进行了评论,但保留了它,以便您可以看到我想要做的事情。

您的想法或提示表示赞赏。

这是我的主要代码:

public class Main {

    public static void main(String[] args) {
        MainMenu menu = new MainMenu();
        menu.pack();
        menu.setVisible(true);
    }
}

这是我的mainMenu代码:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

    public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");

        public MainMenu() {
            super("RPG Main Menu");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel mainMenu = new JPanel();
            mainMenu.setLayout(new FlowLayout());
            startNewGame.setMnemonic('n');
            loadOldGame.setMnemonic('l');
            seeInstructions.setMnemonic('i');
            startNewGame.addActionListener(this);
            loadOldGame.addActionListener(this);
            seeInstructions.addActionListener(this);
            mainMenu.add(startNewGame);
            mainMenu.add(loadOldGame);
            mainMenu.add(seeInstructions);
            setContentPane(mainMenu);

        }

        public void actionPerformed(ActionEvent evt) {
            Object source = evt.getSource();
            if (source == startNewGame) {
                // StartNewGame code goes here
                // mainMenu.removeAll();
            }
            if (source == loadOldGame) {
                // LoadOldGame code goes here
            }
            if (source == seeInstructions) {
                // Quit code goes here
            }
        }
    }

5 个答案:

答案 0 :(得分:2)

请考虑使用CardLayout来管理共享相同显示空间的两个或多个组件(通常为JPanel个实例)。这样,您就不必在运行时添加和删除组件。

答案 1 :(得分:1)

您没有对mainMenu actionPerformed use的引用。如果使用按钮声明mainMenu。它会起作用。

答案 2 :(得分:1)

您需要将mainMenu作为成员变量:

 public class MainMenu extends JFrame implements ActionListener {
        JButton startNewGame = new JButton("Start a New Game");
        JButton loadOldGame = new JButton("Load an Old Game");
        JButton seeInstructions = new JButton("Instructions");
        JPanel mainMenu = new JPanel();

为什么你觉得有必要重复使用这个对象?

答案 3 :(得分:0)

问题是actionPerformed方法试图调用超出范围的JPanel mainMenu,即从mainMenu方法看不到actionPerformed变量。

解决此问题的一种方法是在类本身中使用JPanel mainMenu声明,并使其成为类的所有实例方法都可以访问的实例字段。

例如:

public class MainMenu extends JFrame implements ActionListener
{
    ...
    JPanel mainMenu;

    public MainMenu()
    {
        ...
        mainMenu = new JPanel();
        ...
    }

    public void actionPerformed(ActionEvent e)
    {
        ...
        mainMenu.removeAll();
    }
}

答案 4 :(得分:0)

避免尝试“重复使用”东西。计算机完全能够整理。专注于使你的代码清晰。

因此,不要试图整理面板,只需用新面板替换它。

通常,编写侦听器的更好方法是作为匿名内部类。其中的代码可以访问封闭范围中的最终变量以及封闭类的成员。所以,如果你使mainMenu成为最终的ActionListener匿名内部类,那么你的代码至少应该编译。

也不要尝试“重用”类。尝试让每个类做一个明智的事情,并避免继承(实现)。几乎从不需要扩展JFrame,所以不要这样做。为每个操作创建ActionListener,而不是尝试确定事件源。

另请注意,您应始终在AWT事件调度线程上使用Swing组件。更改main方法以添加样板:

public static void main(final String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
        runEDT();
    }});
}