2016-12-14 2 views
1

CardLayout을 사용하여 게임용 UI를 작성하려고하는데 카드 전환 방법으로 revalidate() 및 repaint()를 사용 했음에도 불구하고 업데이트 할 수없는 것처럼 보입니다. 이 프로그램은 CardLayout을 사용하여 JFrame 내부에서 JPanels를 전환하는 개념을 증명합니다. 한 번 성공적으로 수행 할 수 있다면 다른 JPanels와 프로세스를 반복 할 수 있기 때문입니다. 버그가 스레딩 또는 UI 업데이트와 관련이 있는지 여부는 확실하지 않습니다. 이 해결CardLayout UI를 업데이트하려면 어떻게합니까?

/* 
* 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(); 
      } 
     }); 
    } 
} 
시간에 너무 많은

감사합니다,

: 어쨌든, 여기 내 코드는 내가 camickr에 의해 주어진 the link에 CardLayoutDemo의 클래스 구조를 극복하여 다양한 변경을

(주셔서 감사합니다 당신의 도움을위한 camickr).

/* 
* 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'은 어떤 패널의 레이아웃 관리자로 설정되지 않습니다. [이 답변] (http://stackoverflow.com)에 표시된 [[CardLayout'] (http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html)이 있습니다./a/5786005/418556). –

+0

[Swing tutorial] (http://docs.oracle.com/javase/tutorial/uiswing/TOC.html)에도 실제 예제가 포함되어 있습니까? 뿐만 아니라 스윙 튜토리얼을 다른 스윙 기본 사항에 대한 참조로 사용할 수 있습니다. – camickr

답변

2

클래스의 전체 구조가 잘못 :

여기 내 솔루션입니다. 하나는 정적 변수와 메소드를 모두 사용해서는 안됩니다.

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

위의 사항은 필요하지 않습니다.

다른 레이아웃 관리자와 마찬가지로 패널에 구성 요소를 추가하려면 add(...) 메서드를 사용하면됩니다.

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

CardLayout에서 사용할 제약 조건을 지정해야합니다.

카드를 교환하려고 할 때 revalidate() 및 repaint()가 필요하지 않습니다.

실습 예제는 How to Use CardLayout에서 스윙 튜토리얼의 섹션을 읽어 보는 것이 좋습니다. 이 예제는 스윙 규칙을 따르도록 코드를보다 잘 구성하는 방법을 보여줍니다. 그런 다음 요구 사항에 맞는 작업 예제를 수정할 수 있습니다.

관련 문제