我正在开发我的第一个awt游戏。我正在尝试在单击按钮时将图标设置为按钮(在某些情况下)。这是代码的相关部分:
if (tileIsMemTile) {
System.out.println("!!! Right Tile !!!");
memTile.setBackground(Color.red);
numberOfMemTilesToGuess -= 1;
System.out.println("It rest " + numberOfMemTilesToGuess + " tiles to guess");
} else {
System.out.println("!!! Wrong Tile !!!");
Icon falseTileIcon = new ImageIcon(getClass().getResource("wrong.png"));
memTile.setIcon(falseTileIcon);
wrongGuessAction();
}
System.out.println(">>> Action processed >>>");
if (numberOfMemTilesToGuess == 0) {
System.out.println("\n END OF THE LEVEL");
System.out.println("Congratulations, you guessed all the tiles without error !! \n");
dispose();
//TODO !!!! SHOW INTERLEVEL INFORMATION !!!!
if (memGridDimX != maxDimX && memGridDimY != maxDimY) {
if (memGridDimX == memGridDimY)
new Memory(memGridDimX, memGridDimY + 1);
else
new Memory(memGridDimX + 1, memGridDimY);
} else
System.out.println("You have a really good memory my friend!");
}
}
private void wrongGuessAction() {
//TODO !!! FAILED IN LEVEL MESSAGE !!!
try { Thread.sleep(2000); } catch (Exception e1) {}
dispose();
if (memGridDimX == initialDimX && ( memGridDimY == initialDimY || memGridDimY == initialDimY + 1))
new Memory(initialDimX, initialDimY);
else
new Memory(memGridDimX - 1, memGridDimY - 1);
}
所以在我设置了jbutton的图标之后,我想在处理旧的jframe并启动新的jframe(游戏中的下一个级别)之前看到它。但尽管试图延迟执行 dispose()功能:
尝试{Thread.sleep(2000); } catch(例外e1){}
和任何其他延迟函数(例如比较currenttimemillis(),到-t1),我甚至试图使用;
memTile.setBackground(Color.green);
int i = 0;
do {
System.out.println(i); i++;
} while (!memTile.getIcon().equals(Color.green));
实际上最后一个似乎正在工作,但eclipse跳转到调试模式没有任何异常,即使我关闭帧也不会杀死进程。
所以没有任何作用。在每种情况下,框架关闭,我看不到按钮上的图标。如果我评论dispose并让它创建下一帧,旧框架保持不变,图标加载按钮并且正在创建新框架。我无法理解setIcon方法的执行原理。
提前致谢。
// memTile.setBackground(Color.green);
// int i = 0;
//做{
//
// System.out.println(i);我++;
//} while(!memTile.getIcon()。equals(Color.green));
答案 0 :(得分:2)
在AWT事件派发线程上调用ActionListener
。同一个线程还处理任何其他事件,如paint。因此,只要您的actionPerformed()
方法没有返回,就不会绘制任何内容(或者GUI上的任何其他内容都会被更改)。
您应该在此线程之外执行更长时间运行的操作(即启动新线程执行此操作),然后对于GUI更改,稍后使用EventQueue.invokeLater
(或EventQueue.invokeAndWait
)回调。
答案 1 :(得分:1)
PaŭloEbermann给出了正确的答案,但我只想补充一点从不在事件调度线上睡觉!这只会让事情变得更糟。 Swing是功能强大的工具包,但它对错误线程的容忍(在EDT上睡觉,在EDT之外更新UI)是恕我直言人们遇到Swing问题的首要原因。如果在这种情况下使用 RuntimeException 而失败,则会暴露很多错误,因此更容易修复。
答案 2 :(得分:1)
我必须了解有关EventQueue的更多信息。
阅读Concurrency上的Swing教程中的部分。
也许你的Thread.sleep(...)代码应该用Swing Timer代替。 Swing教程还有一节“如何使用Swing Timers”。