私は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
問題の可能性がある静的な使用が行われているようです。状態変数 – MadProgrammer
を読み書きするスレッド間に問題がある可能性があります。あなたの答え@MadProgrammerに感謝します。テストしたところ、paintComponentメソッドがrepaintによって呼び出された時点で、状態が正しく更新されているようです。-s – mageofzema
ループ内にデバッグメッセージを出力できますか? (また、私は間違っているかもしれませんが、 'validate()'は正しいですか? 'revalidate()'や 'invalidate()'はどうですか?このようなことをやってからしばらくです) –