[英]jPanel doesn't redraw, waiting for server messages
我正在创建一个带有套接字的四连接游戏:1个正在运行的服务器和两个应该连接以玩游戏的客户端。 我由于套接字而无法更新的jPanel遇到了一些麻烦(我认为)。
当游戏(客户端)启动时,您将获得一个jPanel,其中包含IP地址输入框和一个提交按钮。 如果按下了提交按钮,我想显示一条消息,表明游戏正在准备中,正在等待第二位玩家加入。
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!input.getText().equals("")) try {
prefs.put("SavedIp", input.getText());
errorLabel.setText("Preparing game and waiting for other players...");
parentLayout.startGame(input.getText());
} catch (SocketTimeoutException timeout) {
errorLabel.setText("Server timed out.");
} catch (IOException ioeException) {
errorLabel.setText("Server not found!");
} finally {
setTheCursor(Cursor.getDefaultCursor());
}
else errorLabel.setText("Enter an IP adress");
}
});
但是,在startGame方法中,将创建一个新的GamePanel,并在该构造函数中创建一个新的PlayField,并在该PlayField中使用套接字创建一个新的连接。
连接后,它将运行方法checkForNextAction
来查看它是否从服务器接收到消息。 它一直运行该方法,直到服务器发送消息为止。
问题:当我按提交时,我看不到消息出现。 而是挂起,直到第二个玩家加入为止,然后服务器发送一条消息,表明游戏可以开始并且显示了游戏板。 我不能立即将消息更改为我设置的文本吗? jPanel可能不会更新,因为它正在运行方法并等待消息到来。
我在游戏中也遇到类似的问题。 当玩家将硬币放入一列中时,此移动将发送到服务器,但硬币不会在jPanel上绘制。 而是挂起/冻结。 另一个客户采取行动, 只有第一个客户的jPanel才会使用第一个举动的硬币和第二个举动的另一个玩家的硬币进行更新。 因此看来,此举只有在其他玩家采取行动之后才会被平局。
有人有主意吗? 我试图使用this.revalidate()
类的东西,但是在他执行startGame方法之前,我似乎无法强迫jPanel更新。
您的问题是Swing线程问题,因为等待的代码会暂停Swing事件线程,从而冻结所有GUI绘制和用户交互。 解决方案:使用诸如SwingWorker之类的后台线程来等待您。 请在Swing中检查并发性 。
就像是,
submitButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!input.getText().equals("")) {
prefs.put("SavedIp", input.getText());
errorLabel.setText("Preparing game and waiting for other players...");
final ParentWorker parentWorker = new ParentWorker(input.getText());
parentWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
setTheCursor(Cursor.getDefaultCursor());
try {
parentWorker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
// here's where you check for your socket or io exceptions
}
}
}
});
parentWorker.execute();
// parentLayout.startGame(input.getText());
} else {
errorLabel.setText("Enter an IP adress");
}
}
});
和...
class ParentWorker extends SwingWorker<Void, Void> {
private String text;
public ParentWorker(String text) {
this.text = text;
}
@Override
protected Void doInBackground() throws Exception {
parentLayout.startGame(text);
return null;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.