我试图用Java编写一个简单的游戏。基本结构是我在不同时间添加/删除的JFrame
个JPanels
。在启动时,有JPanel
个基本菜单(开始游戏,高分等)。一旦"开始"按下按钮它切换到一个水平选择器面板,有三个按钮来选择游戏的难度级别。按下三个按钮中的任何一个后,它会切换到另一个面板,该面板将显示三秒倒计时,然后是实际游戏。所有三个按钮都调用相同的方法,只是传入了不同的难度值。
我让所有单独的部分工作正常,但我从水平选择面板到倒计时的转换遇到了麻烦。如果我不使用线程,屏幕会在按下按钮时冻结,并且不会切换到新面板。我已经尝试过搞乱线程了,但是我对它们了解得太多而且只取得了有限的成功(我已经得到了它,所以它会成功切换一些时间,但不是一贯的)。
就代码而言,在级别选择面板中,我有类似于按下按钮点击的内容:
private class ButtonClickedListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
gui.newLevel(1);
}
}
代替gui.newLevel(1)
,我已经开始讨论新的线程并从中调用方法。
newLevel()
方法如下:
getContentPane().removeAll();
levelPanel = new LevelPanel(levelNum, this);
add(levelPanel);
validate();
levelPanel.start();
我从开始菜单JPanel
切换到关卡选择器面板时再次使用非常相似的代码(再次,按钮上有ActionListener
),这样就可以了。
LevelPanel的start()
方法初始化新JPanel
的值并在屏幕上显示倒计时(目前使用以下代码,尽管我在{{1}中添加了类似的内容在显示实际游戏之前代替):
newLevel()
我真的很感激有任何帮助使这个代码工作,我很确定某种线程是要走的路,但我不太确定在哪里/如何。任何建议和/或代码样本都会很棒!
提前致谢!
编辑:我最后使用计时器而不是try {
Thread.sleep(1000);
//update countdown number
validate();
repaint();
Thread.sleep(1000);
//update countdown number
validate();
repaint();
Thread.sleep(1000);
//update countdown number
validate();
repaint();
} catch (Exception e) {
System.out.println(e);
}
//start game
来重写倒计时,这解决了问题的一部分,其余部分我最终想通了,与GUI完全无关东西,这就是为什么我没想到要先检查它。
答案 0 :(得分:6)
在EDT期间永远不会使用Thread.sleep(1000);
,此代码导致GUI冻结是un_resposible,直到新事件调用EDT或鼠标悬停在上面也可以活着这个容器
1)有两种方法可以通过工具来实现Swing GUI中的任何事件
Swing Timer
在Thread.sleep(1000);
SwingWorker
延迟推迟
答案 1 :(得分:5)
布局和绘画必须在EDT中完成。使用SwingUtilities.invokeAndWait
来调用validate()
和repaint()
答案 2 :(得分:0)
您可以使用TimerTask延时启动一些代码:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
invokeLater(); // This starts after [delay] ms
// and - if given - will run every [period] ms.
}
}, delay, period);
你可以解决这个问题,虽然这不是一个很好的解决方案。
//编辑:(参见注释)你应该正确地同步对gui的访问,否则它会给你错误。