2009-02-22 53 views
1

G'day全部,难以从Jpanel中删除所有组件

我正在编写项目的主菜单。菜单正常显示。我还为菜单上的三个按钮设置了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 
      } 
     } 
    } 

回答

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

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

1

您不必MAINMENU的actionPerformed使用参考。如果你用按钮声明mainMenu。它会工作。

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

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

+0

谢谢扎克。我会考虑CardLayout。 – elwynn 2009-02-22 07:30:11

0

避免尝试“重复使用”的东西。电脑很有能力整理。集中精力让你的代码清晰。

因此,不要试图整理面板,只需更换一个新的面板。

一般来说,编写监听器的更好方法是匿名内部类。这些代码中的代码将访问封闭范围中的最终变量以及封闭类的成员。所以,如果你使得最终的mainMenu和你的匿名内部类,你的代码至少应该编译。

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

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

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