Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 很难从Jpanel中删除所有组件_Java_Swing_Components_Jpanel - Fatal编程技术网

Java 很难从Jpanel中删除所有组件

Java 很难从Jpanel中删除所有组件,java,swing,components,jpanel,Java,Swing,Components,Jpanel,一整天 我正在为一个项目编写主菜单。菜单显示正确。我还为菜单上的三个按钮设置了ActionListeners 我想做的是,当用户选择开始一个新游戏时,重新使用JPanel来创建一组新的单选按钮 然而,为了从JPanel中删除现有组件而执行的编码操作让我感到困惑。我知道removeAll在某种程度上很重要,但不幸的是,NetBeans通知我无法在ActionPerformed中的主菜单JPanel对象上调用它。因此,我在下面的代码中注释了它,但保留了它,以便您可以看到我正在尝试做什么 感谢您的想法

一整天

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

我想做的是,当用户选择开始一个新游戏时,重新使用JPanel来创建一组新的单选按钮

然而,为了从JPanel中删除现有组件而执行的编码操作让我感到困惑。我知道removeAll在某种程度上很重要,但不幸的是,NetBeans通知我无法在ActionPerformed中的主菜单JPanel对象上调用它。因此,我在下面的代码中注释了它,但保留了它,以便您可以看到我正在尝试做什么

感谢您的想法或提示

这是我的主要代码:

public class Main {

    public static void main(String[] args) {
        MainMenu menu = new MainMenu();
        menu.pack();
        menu.setVisible(true);
    }
}
这是我的主菜单代码:

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

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

您没有对主菜单操作的引用。如果您使用按钮声明主菜单。它会起作用。

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

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

您需要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();
为什么您觉得需要重新使用此对象?

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

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

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

避免重复使用这些东西。计算机很能整理东西。集中精力使代码清晰

因此,与其试图整理面板,不如换一个新的

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

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

还要注意,您应该始终在AWT事件分派线程上使用Swing组件。更改主要方法以添加样板文件,如:

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

避免重复使用东西。计算机很能整理东西。集中精力使代码清晰

因此,与其试图整理面板,不如换一个新的

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

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

还要注意,您应该始终在AWT事件分派线程上使用Swing组件。更改主要方法以添加样板文件,如:

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

谢谢你,扎克。我会考虑卡式布局,谢谢扎克。我会考虑卡片布局。