2016-12-14 3 views
1

J'essaie de créer une interface utilisateur pour un jeu utilisant CardLayout et je n'arrive pas à le mettre à jour malgré l'utilisation de revalidate() et repaint() dans ma méthode de changement de carte. Le programme est conçu comme une preuve de concept de commutation de JPanels à l'intérieur d'un JFrame en utilisant CardLayout, car si je peux le faire une fois avec succès, je pourrais répéter le processus avec d'autres JPanels. Vous ne savez pas si le bogue concerne le thread ou simplement la mise à jour de l'interface utilisateur. Quoi qu'il en soit, voici mon code:Comment puis-je mettre à jour mon interface utilisateur CardLayout?

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package nationsapp; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JButton; 
import javax.swing.JLabel; 
import javax.swing.SwingUtilities; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.awt.CardLayout; 
/** 
* 
* @author StephenAHyberger 
*/ 
public abstract class NationsApp { 
    //Initiates the JFrame for the application 
    public static JPanel deck = new JPanel(); 

    //Initiates the CardLayout and its elements for the application 
    public static CardLayout deckShuffle = new CardLayout(); 
    public static String MENUCARD = "MENUCARD"; 
    public static String GAMECARD = "GAMECARD"; 

    //Initiates all the children of the JFrame. Uses CardLayout. 
    public static void init() { 
     //Initiates the JFrame 
     JFrame frame = new JFrame("Nations"); 

     //Initiates the first card and its children 
     JPanel menuPanel = new JPanel(); 
     JButton newGameBtn = new JButton("New Game"); 
     JLabel noteOne = new JLabel("Panel 1"); 

     //Adds the children of the first card into the component heiarchy 
     menuPanel.add(newGameBtn); 
     menuPanel.add(noteOne); 

     //Adds all event listeners on the first card 
     newGameBtn.addActionListener(new NewGame()); 

     //Initiates the second card and its children 
     JPanel gamePanel = new JPanel(); 
     JLabel noteTwo = new JLabel("Panel 2"); 

     //Adds the children of the second card into the component heiarchy 
     gamePanel.add(noteTwo); 

     //Adds the cards to the deck 
     deck.add(menuPanel); 
     deck.add(gamePanel); 

     //Adds the deck to the JFrame 
     frame.add(deck); 

     //Sets up the CardLayout 
     deck.setLayout(new CardLayout()); 
     deckShuffle.addLayoutComponent(frame, MENUCARD); 
     deckShuffle.addLayoutComponent(frame, GAMECARD); 

     //Sets up JFrame behavior and renders the application 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
    public static void setWindow(String PLACEHOLDER) { 
     CardLayout cl = (CardLayout)(deck.getLayout()); 
     cl.show(deck, PLACEHOLDER); 
     deck.revalidate(); 
     deck.repaint(); 
    } 
    private static class NewGame implements ActionListener { 
     @Override 
     public void actionPerformed(ActionEvent e) { 
      NationsApp.setWindow(GAMECARD); 
     } 
    } 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       NationsApp.init(); 
      } 
     }); 
    } 
} 

Merci beaucoup pour votre temps,

RESOLU:

J'ai fait des changements importants par adaptation de la structure de classe de CardLayoutDemo dans the link donnée par camickr (Merci camickr pour votre aide).

Voici ma solution:

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package nationsapp; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
/** 
* 
* @author StephenAHyberger 
*/ 
public class NationsApp implements ActionListener { 
    //Creates a JPanel to implement a CardLayout 
    JPanel deck; 

    //Creates constraints for the CardLayout 
    final static String MENUCARD = "MENUCARD"; 
    final static String GAMECARD = "GAMECARD"; 

    public void init(Container pane) { 
     //Creates the first card 
     JPanel menuCard = new JPanel(); 
     JButton newGameBtn = new JButton("New Game"); 
     menuCard.add(new JLabel("Panel 1")); 
     menuCard.add(newGameBtn); 

     //Adds EventListeners to the first card 
     newGameBtn.addActionListener(this); 

     //Creates the second card 
     JPanel gameCard = new JPanel(); 
     gameCard.add(new JLabel("Panel 2")); 

     //Creates the deck for the cards 
     deck = new JPanel(new CardLayout()); 
     deck.add(menuCard, MENUCARD); 
     deck.add(gameCard, GAMECARD); 

     pane.add(deck); 
    } 
    private static void render() { 
     //Create and set up the window 
     JFrame frame = new JFrame("Nations"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create application class 
     NationsApp app = new NationsApp(); 
     app.init(frame.getContentPane()); 

     //Display the window 
     frame.pack(); 
     frame.setVisible(true); 
    } 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     CardLayout cl = (CardLayout)(deck.getLayout()); 
     cl.show(deck, GAMECARD); 
    } 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       render(); 
      } 
     }); 
    } 
} 
+0

'deckShuffle' n'est jamais défini en tant que gestionnaire de disposition d'un panneau. Il y a un [[CardLayout'] de travail (http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) montré dans [cette réponse] (http://stackoverflow.com/a/5786005/418556). –

+0

Le [tutoriel Swing] (http://docs.oracle.com/javase/tutorial/uiswing/TOC.html) qui contient également un exemple de travail? Non seulement le tutoriel Swing peut être utilisé comme référence pour d'autres bases de Swing. – camickr

Répondre

2

La structure entière de votre classe est faux. Pour cela, vous ne devriez pas utiliser toutes les variables et méthodes statiques.

deckShuffle.addLayoutComponent(frame, MENUCARD); 
    deckShuffle.addLayoutComponent(frame, GAMECARD); 

Ci-dessus n'est pas nécessaire. Utilisez simplement la méthode add(...) pour ajouter des composants au panneau comme vous le feriez avec n'importe quel autre gestionnaire de disposition.

deck.add(menuPanel, ...); 
    deck.add(gamePanel, ...); 

Vous devez spécifier la contrainte à utiliser par CardLayout.

Vous n'avez pas besoin de revalidate() et repaint() lorsque vous tentez d'échanger des cartes.

Je vous suggère de commencer par lire la section du tutoriel Swing sur How to Use CardLayout pour un exemple de travail. L'exemple vous montrera comment mieux structurer votre code pour suivre les conventions Swing. Vous pouvez ensuite modifier l'exemple de travail pour vos besoins.