难以从 Jpanel 中删除所有组件
Posted
技术标签:
【中文标题】难以从 Jpanel 中删除所有组件【英文标题】:Difficulty removing all components from a Jpanel 【发布时间】:2010-10-09 03:18:37 【问题描述】:万事如意,
我正在为一个项目编写一个主菜单。菜单正确显示。我还为菜单上的三个按钮设置了 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);
这是我的主菜单代码:
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
【问题讨论】:
【参考方案1】:考虑改用CardLayout
,它管理共享相同显示空间的两个或多个组件(通常是JPanel
实例)。这样您就不必在运行时添加和删除组件。
【讨论】:
谢谢扎克。我会考虑 CardLayout。【参考方案2】:你需要 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】:您没有对 mainMenu actionPerformed 使用的引用。如果您使用按钮声明 mainMenu。它会起作用的。
【讨论】:
【参考方案4】:问题是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();
【讨论】:
【参考方案5】:避免尝试“重复使用”东西。计算机非常有能力进行整理。专注于让你的代码清晰。
因此,与其尝试整理面板,不如用新面板替换它。
通常,编写侦听器的更好方法是匿名内部类。其中的代码将可以访问封闭范围内的最终变量和封闭类的成员。所以,如果你将 mainMenu
设为 final 并且 ActionListener
s 匿名内部类,你的代码至少应该可以编译。
也不要尝试“重用”类。尽量让每个类做一件明智的事情,并避免继承(实现)。几乎不需要扩展JFrame
,所以不要这样做。为每个操作创建一个ActionListener
,而不是尝试确定事件源。
另外请注意,您应该始终在 AWT 事件调度线程上使用 Swing 组件。更改 main
方法以添加样板文件,例如:
public static void main(final String[] args)
java.awt.EventQueue.invokeLater(new Runnable() public void run()
runEDT();
);
【讨论】:
以上是关于难以从 Jpanel 中删除所有组件的主要内容,如果未能解决你的问题,请参考以下文章