2015-04-02 105 views
0

我有一個JFrame和2個JPanel。一個面板是帶按鈕的開始屏幕。另一個面板是遊戲屏幕。當我刪除開始屏幕並顯示遊戲屏幕時,JFrame沒有任何反應。開始屏幕是持久的但不可用,並且遊戲在後臺運行而不更新屏幕。當遊戲結束時,開始屏幕再次可用。我在網上到處搜索一個解決方案。他們都說removeAll,重新驗證,重繪,打包或getContentPane.removeAll。我還沒有能夠得到任何這些解決方案的工作。這裏是驅動器類:交換JPanel,第二JPanel不顯示

public class BallDriver extends JFrame { 

private static final long serialVersionUID = 1L; 

int width = 500; 
int height = 500; 

Container cont; 
StartScreen start; 
BallGame ballGame; 

public BallDriver() { 
    cont = getContentPane(); 
    startScreen(); 
} 

private void startScreen() { 

    setTitle("BallGame"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setSize(new Dimension(width, height)); 
    setPreferredSize(new Dimension(500,500)); 

    start = new StartScreen(); 
    JButton[] startButtons = start.getButtons(); 
    setupButtons(startButtons); 
    add(start, BorderLayout.CENTER);   
} 

private void startGame(String difficulty) throws InterruptedException { 
    removeAll(); 
    setSize(new Dimension(width, height)); 
    setPreferredSize(new Dimension(width, height)); 

    ballGame = new BallGame(width, height); 
    ballGame.setPreferredSize(new Dimension(width, height)); 
    add(ballGame, BorderLayout.CENTER); 
    revalidate(); 
    repaint(); 

    while(!ballGame.endGame()) { 
     ballGame.moveBall(); 
     ballGame.repaint(); 
     try { 
      Thread.sleep(2); 
     } catch (InterruptedException e) { e.printStackTrace(); } 
    } 

    removeAll(); 
    add(start, BorderLayout.CENTER); 
    revalidate(); 
    repaint(); 
} 

private void setupButtons(final JButton[] buttons) { 
    for (JButton button : buttons) { 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       Object object = e.getSource(); 
       try { 
        if (object == buttons[0])      
         startGame(StartScreen.MODE_EASY); 
        if (object == buttons[1]) 
         startGame(StartScreen.MODE_NORMAL); 
        if (object == buttons[2]) 
         startGame(StartScreen.MODE_HARD); 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 

public static void main(String[] args){ 
    SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
       BallDriver ballDriver = new BallDriver(); 
       ballDriver.setVisible(true); 
     } 
    }); 
}  

}

編輯: 我已經更新了類使用cardlayout,但會發生同樣的事情。

public class BallDriver extends JFrame { 

private static final long serialVersionUID = 1L; 

int width = 500; 
int height = 500; 

JPanel cardPanel = new JPanel(); 
Container cont; 
StartScreen start; 
BallGame ballGame; 
CardLayout cardLayout = new CardLayout(); 

public BallDriver() { 
    setTitle("BallGame"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setSize(new Dimension(width, height)); 
    setPreferredSize(new Dimension(width, height)); 

    cardPanel.setLayout(cardLayout); 
    cont = getContentPane(); 
    add(cardPanel, BorderLayout.CENTER); 
    startScreen(); 

} 

private void startScreen() { 
    start = new StartScreen(); 
    JButton[] startButtons = start.getButtons(); 
    setupButtons(startButtons); 
    cardPanel.add(start, "start");  
    cardLayout.show(cardPanel, "start"); 
} 

private void startGame(String difficulty) throws InterruptedException { 

    ballGame = new BallGame(width, height); 
    cardPanel.add(ballGame, "game"); 
    cardLayout.show(cardPanel, "game"); 
    cardPanel.revalidate(); 
    cardPanel.repaint(); 

    while(!ballGame.endGame()) { 
     System.out.println("Running"); 
     ballGame.moveBall(); 
     ballGame.repaint(); 
     try { 
      Thread.sleep(2); 
     } catch (InterruptedException e) { e.printStackTrace(); } 
    } 
} 

private void setupButtons(final JButton[] buttons) { 
    for (JButton button : buttons) { 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       Object object = e.getSource(); 
       try { 
        if (object == buttons[0])      
         startGame(StartScreen.MODE_EASY); 
        if (object == buttons[1]) 
         startGame(StartScreen.MODE_NORMAL); 
        if (object == buttons[2]) 
         startGame(StartScreen.MODE_HARD); 
       } catch (InterruptedException e1) { 
        e1.printStackTrace(); 
       } 
      } 
     }); 
    } 
} 

public static void main(String[] args){ 
    SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
       BallDriver ballDriver = new BallDriver(); 
       ballDriver.setVisible(true); 
     } 
    }); 
}  

}

+0

聽起來就像CardLayout的情況 – ControlAltDel 2015-04-02 20:18:58

+0

CardLayout工作得很好。問題是我在同一個線程上更新JPanel。我需要通過一個新線程來運行遊戲。 – 2015-04-03 17:19:19

回答

2

CardLayout可以將多個面板添加到Container,僅顯示1面板的時間,與對面板之間切換的能力。您可以設置家長的佈局CardLayout,添加面板到相框指定名稱的約束:

CardLayout layout = new CardLayout(); 
JFrame frame = new JFrame(); 
frame.setLayout(layout); 

JPanel panel1 = new JPanel(); 
JPanel panel2 = new JPanel(); 

frame.add(panel1, "first"); 
frame.add(panel2, "second"); 

添加的第一個面板是第一TK顯示。要切換面板,請撥打CardLayout#show(Container, String),傳入面板的父級(視爲「」卡座))和所需特定面板的名稱(視爲「」)。

layout.show(frame, "second"); 

人的通病有CardLayout是有父的大小調整爲當前面板的尺寸。這可以通過extending upon CardLayout