【发布时间】:2015-03-06 09:16:10
【问题描述】:
我对 Swing 很陌生,但对 Java 不是。无论如何,我有一个国际象棋程序。这是游戏循环类中重要的部分:
public class game {
static Board gameboard = new Board();
public static boolean waitstatus = true;
public static char currentfaction = 'w';
public static boolean done = false;
public static boolean resigned = false;
public static boolean wplayern = false;
public static boolean bplayern = false;
public static gui boardwindow = new gui();
public static void main(String[] args) {
gameboard.init(8, 8);
gui.startGUI(boardwindow);
runner();
while (true) {
//spin
}
}
public static void runner() {
done = false;
resigned = false;
wplayern = false;
bplayern = false;
boolean stalemate = false;
while (true) {
//The loop stuff
}
}
public static void resetGame() {
if (!done) {
System.out.println("Game's not finished yet!");
} else {
gameboard.restart();
waitstatus = true;
currentfaction = 'w';
done = false;
resigned = false;
wplayern = false;
bplayern = false;
boardwindow.redraw();
rerun();
}
}
public static void rerun() {
runner();
}
}
这就是有问题的代码。顺便说一句,boardwindow 是一个 gui 对象,gameboard 是我的内部逻辑游戏板数组,redraw() 具有 gui 重绘(更新棋子的位置),restart() 将内部逻辑板重新启动到原始开始游戏状态。 gui 类是一个swing gui,非常简单,而且效果很好。问题是,在游戏循环中,当它被将死时,循环中断并且 runner() 函数结束。然后,用户应该能够在 gui 中按下新游戏按钮,以在将死后重新启动游戏。新的游戏按钮调用 resetGame()。问题是再次调用 runner() 时 gui 窗口会冻结,我不知道为什么,我想它不需要多个线程。我还有其他按钮可以调用我没有向您展示的函数,这些函数会调用其他函数,例如 restart() 等,它们没有问题,只有在调用 runner() 时才会出现问题。
我知道我的其他代码在格式和约定方面可能很糟糕,但请尽量将答案集中在主要问题上。
谢谢
【问题讨论】:
-
您是否注意到控制台日志中有任何错误?
-
我不确定你的情况,但 Java Swing 中冻结 GUI 的几乎所有问题都与使用 EDT 的错误有关:docs.oracle.com/javase/tutorial/uiswing/concurrency/…
-
不要依赖
static,它不是跨对象通信机制,会炸你的脸 -
控制台日志中没有错误,我意识到 Swing 中 GUI 冻结的大多数问题都来自线程处理不当,但我的问题与我见过的大多数其他示例不同。此时我并不想同时运行两种方法,即使在其他情况下,当我同时运行两种方法时,GUI 也能很好地处理它。我使用静态是因为我不想为游戏创建单独的对象,因为它确实不需要单独的对象。
-
不要阻塞 EDT(事件调度线程)。发生这种情况时,GUI 将“冻结”。有关详细信息和修复,请参阅 Concurrency in Swing。
标签: java swing user-interface event-dispatch-thread