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
}
}
}
答案 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();
}});
}