很难从 Jpanel 中移除所有组件

发布于 2024-07-14 04:20:58 字数 2059 浏览 6 评论 0原文

大家好,

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

我想要做的是,当用户选择“开始新游戏”时,将 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
            }
        }
    }

G'day all,

I am coding a main menu for a project. The menu displays properly. I have also set up ActionListeners for the three buttons on the menu.

What I wish to do is reuse the JPanel for a new set of radio buttons when the user chooses "Start a New Game".

However, coding ActionPerformed to remove the existing components from the JPanel has me stumped. I know removeAll is somehow important, but unfortunately NetBeans informs me I cannot call it on my mainMenu JPanel object within ActionPerformed. So i have commented it out in my code below, but left it in so you can see what I am trying to do.

Your thoughts or hints are appreciated.

Here is my main code:

public class Main {

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

Here is my mainMenu code:

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
            }
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

飘落散花 2024-07-21 04:20:59

问题是 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();
    }
}

The problem is that the actionPerformed method is trying to call the JPanel mainMenu which is out of scope, i.e. the mainMenu variable is not visible from the actionPerformed method.

One way to get around this is to have the JPanel mainMenu declaration in the class itself and make it an instance field which is accessible to all instance methods of the class.

For example:

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

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

    public void actionPerformed(ActionEvent e)
    {
        ...
        mainMenu.removeAll();
    }
}
纸短情长 2024-07-21 04:20:59

避免尝试“重用”东西。 计算机非常有能力进行整理。 专注于让你的代码清晰。

因此,与其尝试清理面板,只需更换新面板即可。

一般来说,编写侦听器的更好方法是使用匿名内部类。 其中的代码将可以访问封闭范围中的最终变量以及封闭类的成员。 因此,如果您将 mainMenu 设置为最终状态并且将 ActionListener 设为匿名内部类,那么您的代码至少应该可以编译。

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

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

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

Avoid attempting to "reuse" stuff. Computers are quite capable of tidying up. Concentrate on making you code clear.

So instead of attempting to tidy up the panel, simply replace it with a new one.

Generally a better way to write listeners is as anonymous inner classes. Code within these will have access to final variables in the enclosing scope and to members of the enclosing class. So, if you make mainMenu final and you ActionListeners anonymous inner classes, your code should at least compile.

Also don't attempt to "reuse" classes. Try to make each class do one sensible thing, and avoid inheritance (of implementation). There is almost never any need to extend JFrame, so don't do that. Create an ActionListener for each action, rather than attempting to determine the event source.

Also note, you should always use Swing components on the AWT Event Dispatch Thread. Change the main method to add boilerplate something like:

public static void main(final String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
        runEDT();
    }});
}
飘落散花 2024-07-21 04:20:58

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

Consider using a CardLayout instead, which manages two or more components (usually JPanel instances) that share the same display space. That way you don't have to fiddle with adding and removing components at runtime.

梦里°也失望 2024-07-21 04:20:58

您需要 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();

为什么您觉得需要重新使用这个对象?

You need mainMenu to be a member variable:

 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();

Why do you feel the need to re-use this object?

阳光①夏 2024-07-21 04:20:58

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

You don't have a reference to mainMenu actionPerformed use. If you declare mainMenu with the buttons. It would work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文