2017-10-17 75 views
0

我正在用Java構建一個掃雷遊戲。在GUI設計中,我遇到了一個問題。這是我的遊戲窗口。 enter image description here在加載JFrame之後,是否可以將新的JPanel添加到JFrame?

灰色區域應該包含實際的雷場。我想要發生的是在玩家點擊開始遊戲後,我想要加載包含實施礦場的JPanel。但是,似乎JFrame加載後我無法再添加JPanel,我是正確的?我嘗試在另一個線程中運行mine字段的添加(睡眠幾秒鐘,然後添加JPanel),以查看是否有可能,並且沒有結果。

public GameWindow(){ 

     super("Minesweeper"); 
     this.setLayout(new BorderLayout()); 

     this.gamePanel = new GamePanel(new GridLayout(BOARD_SIZE,BOARD_SIZE,1,1)); 

     this.timerPanel = new TimerPanel(new BorderLayout(15,15)); 

     this.timerPanel.initializeFlagLabel(8); 

     this.mineField = new Button[BOARD_SIZE][BOARD_SIZE]; 
     int buttonCounter = 0; 

     for(int i = 0; i < BOARD_SIZE; i ++){ 

      for(int j = 0; j < BOARD_SIZE; j++){ 

       mineField[i][j] = new Button(); 
       mineField[i][j].setName(Integer.toString(buttonCounter++)); 
       mineField[i][j].setBackground(Color.GRAY); 
       mineField[i][j].setPreferredSize(new Dimension(10,10)); 
       mineField[i][j].addMouseListener(this); 
       gamePanel.add(mineField[i][j]); 
      } 
     } 
     Container container = getContentPane(); 

     container.add(timerPanel,BorderLayout.PAGE_START); 

     container.add(new MenuPanel(this), BorderLayout.WEST); 

     new Thread(new Runnable(){//Here I want to wait for the JFrame to 
            //load and then to add the gamePanel. 
       public void run(){ 
        try { 
         Thread.sleep(4000); 
         container.add(gamePanel, BorderLayout.CENTER); 
        } catch (InterruptedException e) { 
         // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 
     }); 

     this.setSize(800,640); 
     this.setLocationRelativeTo(null); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setResizable(false); 
     this.setVisible(true); 

    } 

總結我的問題是,是否有可能在運行時新JPanels添加到JFrame的,如果是的話我該怎麼辦呢?

回答

2

簡而言之,是的。您需要撥打revalidaterepaint觸發您更新的容器的佈局和通道。

較長的答案是,可能不是你這樣做的方式。

除了事實上你從來沒有真的startThread,Swing不是線程安全的,你不應該在事件派發線程的上下文之外更新UI。

在您的情況下,替代(並且更安全)的解決方案將使用Swing Timer。有關更多詳細信息,請參見How to use Swing Timers

+0

感謝您指出我忘了開始線程。 – Keselme

+0

讓menuPanel實現Observable和JFrame來實現觀察者是不是一個好主意,並且當開始遊戲被點擊時menuPanel會通知JFrame加載gamePanel? – Keselme

+0

那麼,你基本上描述的是一個MVC,所以是的,這不是一個壞主意 – MadProgrammer

1

在開始遊戲的動作監聽器中,您可以將jpanel添加到預先創建的幀中。您也可能需要repaint()revalidate()

+0

是不是一個好主意,讓menuPanel實現Observable和JFrame來實現觀察者,當開始遊戲被點擊時,menuPanel將通知JFrame通過使用repaint()加載gamePanel? – Keselme