我是Java Swing的新手,我一直致力于创建一个Connect 4 Game,它通过带有gameRoom的服务器支持多人游戏。我已经解决了这个特殊的问题将近2天,并且在解决它时遇到了一些问题,例如停止使用Thread.sleep并彻底测试Game对象是否正确地传入和传出服务器。
我设计的方式是通过模型的make move命令提交每个动作。为了刷新GUI,服务器将新的Game对象发送回模型并标记控制器属性" setRepaint'是的。然后,计时器定期检查此属性是否为true并调用repaintGrid()方法。
经过几个小时的努力才能让它发挥作用,我无法让游戏面板重新粉刷。
可能会有所帮助的一些要点:
如果我退出应用程序并使用已经移动的Game对象重新启动它,则会绘制面板。问题在于重绘方法。
模型是静态的,每次调用Connect4App.model.getGameFromServer()时都会更新Game属性。不确定这是否会导致问题,但如果我打印正在重新绘制为红色/蓝色的面板,我可以验证服务器在每次迭代时是否成功更新了游戏对象。
框架层次结构如下:guiMain是gamePanel的容器,它有一个gridlayout,每个都由一个GridPanel面板填充。 Grid面板基本上是Connect4 Game标记的插槽,那些是我尝试在repaintGrid方法中更新的插槽
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();
}
}
}
}
任何帮助将不胜感激:-D
答案 0 :(得分:0)
事实证明,我在向对象输出流(游戏状态)发送同一对象时遇到问题而没有重置流,因此这导致客户端不会一直接收更新。上面的重新绘制代码正在运行。关闭线程,再次感谢。