2017-10-17 17 views
0

私はJavaで掃海艇のゲームを構築しています。 GUIの設計中、私は問題に遭遇しました。ここに私のゲームウィンドウです。 enter image description hereJFrameを読み込んだ後、JFrameに新しいJPanelを追加することはできますか?

実際の地雷欄が含まれているはずの灰色の領域です。私がしたいのは、プレイヤーがStart Gameをクリックすると、地雷フィールドの実装を含むJPanelをロードしたいということです。しかし、JFrameがロードされた後、私はもうJPanelを追加できないようです。私は正しいのですか?私は別のスレッドで(数秒間スリープしてから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); 

    } 

、それは実行時にJFrameのに新規のJPanelを追加し、どのように私はそれを行うことができますので、場合することは可能ですか?

答えて

2

短い答えは、はいです。更新したコンテナにレイアウトとペイントパスをトリガするには、revalidaterepaintに電話する必要があります。

長い答えは、おそらくあなたのやり方ではありません。

実際にstartThreadということはありませんが、Swingはスレッドセーフではないため、イベントディスパッチスレッドのコンテキストのUIを更新するべきではありません。

代わりの(そしてより安全な)ソリューションは、Swing Timerを使用することです。詳細については、How to use Swing Timersを参照してください。

+0

私はスレッドを開始するのを忘れていたことを指摘していただきありがとうございます。 – Keselme

+0

menuPanelにObservableを実装させ、オブザーバを実装するためのJFrameを用意することをお勧めします。また、start gameがクリックされたときにmenuPanelがgamePanelをロードするようにJFrameに通知しますか? – Keselme

+0

基本的にはMVCなので、はい、それは悪い考えではありません。 – MadProgrammer

1

開始ゲームのアクションリスナーでは、事前作成されたフレームにjpanelを追加できます。 repaint()またはrevalidate()

+0

menuPanelにObservableを実装し、JFrameにオブザーバを実装させて、ゲーム開始時にmenuPanelがJFrameに通知することをお勧めしますか? repaint()を使ってgamePanelをロードしますか? – Keselme

関連する問題