2016-03-19 20 views
0

私はJava Swingを初めて使いました。私は、gameRoomを備えたサーバーを通じてマルチプレイヤーをサポートするConnect 4ゲームの作成に取り組んできました。私はこの特定の問題をほぼ2日間作業していましたが、解決している間にThread.sleepの使用を停止し、Gameオブジェクトがサーバーとの間で正しく渡されているかどうかを完全にテストしました。スイングタイマーでパネルを再描画しないJava Swing 2D配列

私が設計した方法は、各移動がモデルのmake moveコマンドによって実行されるということです。 GUIをリフレッシュするために、サーバーは新しいGameオブジェクトをモデルに送り返し、コントローラー属性 'setRepaint'をtrueとマークします。タイマーはこの属性が真であるかどうかを定期的にチェックし、repaintGrid()メソッドを呼び出します。

これを動作させようと数時間もたっても、ゲームパネルを再描画することはできません。役立つかもしれない

いくつかのポイント:私は、アプリケーションを終了し、すでにその上に移動しているゲームのオブジェクトでそれを再起動した場合

  • は、パネルが描かれています。問題は、repaintメソッドにあります。

  • モデルは静的で、Connect4App.model.getGameFromServer()が呼び出されるたびに更新されます。これが問題を引き起こすかどうかは確かではありませんが、赤/青で再描画されているパネルを印刷すると、ゲームオブジェクトが各繰り返しでサーバーによって正常に更新されたことを確認できます。

  • フレームの階層は次のとおりです。guiMainは、gridPlayパネルを持つgridlayoutを持つgamePanelのコンテナです。グリッドパネルは、本質的にConnect4ゲームのトークン用のスロットであり、これらは、私は任意の助けをいただければ幸いです

    import java.awt.GridLayout; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.event.MouseAdapter; 
    import java.awt.event.MouseEvent; 
    import javax.swing.JPanel; 
    import javax.swing.Timer; 
    
    public class GameController { 
    
    MouseAdapter me; 
    private JPanel gamePanel; 
    private boolean setRepaint = false; 
    
    /** 
    * Constructor for the Game Controller. Takes in a view and a model 
    * 
    * @param view 
    * @param model 
    */ 
    public GameController() { 
        setupGridPanels(); 
        setupMouseAdapter(); 
        Connect4App.frame.setContentPane(Connect4App.guiMain); 
        Connect4App.frame.setTitle("Game View"); 
        goIntoTimer(); 
    
    } 
    
    /** 
    * Repaint Boolean used by timer. Set to true by external program 
    */ 
    public void setRepaint() { 
        this.setRepaint = true; 
    } 
    
    /** 
    * Swing Timer which checks if it needs to repaint every 8 seconds and if 
    * so, calls repaintGrid 
    */ 
    private void goIntoTimer() { 
        Timer timer = new Timer(50, new ActionListener() { 
         @Override 
         public void actionPerformed(ActionEvent e) { 
          Connect4App.model.getGameFromServer(); 
    
          if (setRepaint == true) { 
           repaintGrid(); 
           setRepaint = false; 
          } 
    
         } 
        }); 
        timer.setRepeats(true); 
        timer.setDelay(8000); 
        timer.start(); 
    
    } 
    
    /** 
    * Sets up the Initial Game Panels in the Connect4App.guiMain panel 
    */ 
    private void setupGridPanels() { 
        this.gamePanel = new JPanel(); 
        this.gamePanel.removeAll(); 
    
        // setting up the layout for, the game board. 
        this.gamePanel.setLayout(new GridLayout(0, Connect4App.model.getGame().getGrid()[0].length)); 
    
        int numberOfRows = Connect4App.model.getGame().getGrid().length; 
        int numberOfColumns = Connect4App.model.getGame().getGrid()[0].length; 
    
        for (int r = 0; r < numberOfRows; r++) { 
         for (int c = 0; c < numberOfColumns; c++) { 
          Connect4App.guiMain.setCircleArc(r, c, new GridPanel(r, c)); 
          this.gamePanel.add(Connect4App.guiMain.getCircleArcs()[r][c]); 
         } 
        } 
        Connect4App.guiMain.add(this.gamePanel); 
    } 
    
    /** 
    * Sets up the mouse pressed event handleres for every panel 
    */ 
    private void setupMouseAdapter() { 
        MouseAdapter mc = new MouseAdapter() { 
    
         @Override 
         public void mousePressed(MouseEvent mc) { 
    
          GridPanel cell = (GridPanel) mc.getSource(); 
    
          // this is the column that should go in the MakeMove message 
          int column = cell.getColumn(); 
          int row = cell.getRow(); 
    
          if (Connect4App.model.getGame().getGrid()[row][column].getState() == 0) { 
           System.out.println("attempting to make move"); 
           Connect4App.model.makeMove(column); 
          } 
         } 
        }; 
    
        for (int r = 0; r < Connect4App.model.getGame().getGrid().length; r++) { 
         for (int c = 0; c < Connect4App.model.getGame().getGrid()[0].length; c++) { 
          Connect4App.guiMain.getCircleArcs()[r][c].addMouseListener(mc); 
         } 
        } 
    } 
    
    void repaintGrid() { 
    
        // --> This is supposed to be working 
        System.out.println("repainting"); 
    
        for (int r = 0; r < Connect4App.model.getGame().getGrid().length; r++) { 
         for (int c = 0; c < Connect4App.model.getGame().getGrid()[0].length; c++) { 
          Connect4App.guiMain.getCircleArcs()[r][c].validate(); 
          Connect4App.guiMain.getCircleArcs()[r][c].repaint(); 
         } 
        } 
    } 
    } 
    

repaintGrid方法で更新しようとするものです:-D

+0

問題の可能性がある静的な使用が行われているようです。状態変数 – MadProgrammer

+0

を読み書きするスレッド間に問題がある可能性があります。あなたの答え@MadProgrammerに感謝します。テストしたところ、paintComponentメソッドがrepaintによって呼び出された時点で、状態が正しく更新されているようです。-s – mageofzema

+0

ループ内にデバッグメッセージを出力できますか? (また、私は間違っているかもしれませんが、 'validate()'は正しいですか? 'revalidate()'や 'invalidate()'はどうですか?このようなことをやってからしばらくです) –

答えて

0

ストリームをリセットせずにオブジェクト出力ストリーム(ゲームの状態)を介して同じオブジェクトを4番目と3番目に送信することに問題があったので、クライアントが常に更新を受け取らない原因となっていました。上の再塗りつぶしのコードが動作していた。スレッドを閉じて、もう一度ありがとう。

関連する問題