2009-02-22 8 views
1

Tous les jours,Difficulté à retirer tous les composants d'un Jpanel

Je suis en train de coder un menu principal pour un projet. Le menu s'affiche correctement. J'ai également mis en place ActionListeners pour les trois boutons du menu. Ce que je souhaite faire est de réutiliser le JPanel pour un nouvel ensemble de boutons radio quand l'utilisateur choisit "Commencer une nouvelle partie". Cependant, en codant ActionPerformed pour supprimer les composants existants du JPanel, j'ai échoué. Je sais que removeAll est en quelque sorte important, mais malheureusement NetBeans m'informe que je ne peux pas l'appeler sur mon objet mainMenu JPanel dans ActionPerformed. Donc je l'ai commenté dans mon code ci-dessous, mais je l'ai laissé pour que vous puissiez voir ce que j'essaie de faire.

Vos pensées ou conseils sont appréciés.

Voici mon code principal:

public class Main { 

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

Voici mon code 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 
      } 
     } 
    } 

Répondre

1

Vous avez besoin mainMenu d'être une variable membre:

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

Pourquoi vous sentez-vous le besoin de réutiliser cet objet?

1

Vous ne disposez pas d'une référence à une utilisation mainMenu actionPerformed. Si vous déclarez mainMenu avec les boutons. Cela fonctionnerait.

0

Le problème est que la méthode actionPerformed tente d'appeler le JPanel mainMenu qui est hors de portée, à savoir la variable mainMenu ne soit pas visible à partir de la méthode actionPerformed. Une façon de contourner ce problème est d'avoir la déclaration JPanel mainMenu dans la classe elle-même et d'en faire un champ d'instance accessible à toutes les méthodes d'instance de la classe.

Par exemple: au lieu

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

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

    public void actionPerformed(ActionEvent e) 
    { 
     ... 
     mainMenu.removeAll(); 
    } 
} 
2

Pensez à utiliser un CardLayout, qui gère deux ou plusieurs composants (généralement JPanel instances) qui partagent le même espace d'affichage. De cette façon, vous n'avez pas à jouer avec l'ajout et la suppression de composants lors de l'exécution.

+0

Merci Zach. Je vais considérer CardLayout. – elwynn

0

Évitez de tenter de «réutiliser» des éléments. Les ordinateurs sont tout à fait capables de ranger. Concentrez-vous sur votre code clair.

Donc, au lieu d'essayer de ranger le panneau, il suffit de le remplacer par un nouveau.

En règle générale, une meilleure façon d'écrire des écouteurs est sous forme de classes internes anonymes. Le code à l'intérieur de ceux-ci aura accès aux variables finales dans la portée englobante et aux membres de la classe englobante. Donc, si vous faites mainMenu final et vous ActionListener classes internes anonymes, votre code devrait au moins compiler.

N'essayez pas non plus de "réutiliser" les classes. Essayez de faire en sorte que chaque classe fasse une chose raisonnable, et évitez l'héritage (de la mise en œuvre). Il n'y a presque jamais besoin d'étendre JFrame, alors ne le faites pas.Créez un ActionListener pour chaque action, plutôt que d'essayer de déterminer la source de l'événement.

Notez également que vous devez toujours utiliser des composants Swing sur le thread AWT Event Dispatch. Changer la main méthode pour ajouter quelque chose comme:

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