我试图通过改变颜色和调用repaint()
方法来闪烁Java图形对象。颜色只会随着最后的更改颜色调用而更新。下面是我的代码:
public void start() {
try {
Color origColor = node.getColor();
for (int i=0; i<noOfFlashes; i++) {
Manager.gui.getDrawGraph().changeNodeColor(node, Color.WHITE);
Thread.sleep(500);
Manager.gui.getDrawGraph().changeNodeColor(node, origColor);
Thread.sleep(500);
}
Manager.gui.getDrawGraph().changeNodeColor(node, Graph.VISITED_NODE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
,改变节点颜色的方法为:
public void changeNodeColor(Node node, Color c) {
node.setColor(c);
repaint();
}
更改节点的颜色与paint组件在同一个类中。
您需要使用单独的线程来管理GUI事件。你可以像Amine建议的那样使用SwingWorker,或者实现Runnable接口,或者扩展Thread类,开发run()
方法,这是你的线程的任务。
你可以阅读这个老问题:我如何在Java中使用SwingWorker ?
SwingWorker教程:http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
创建线程的教程:http://docs.oracle.com/javase/tutorial/essential/concurrency/
颜色只在最后的change color调用中更新。
如果你不使用一个单独的线程,你的gui将冻结,直到方法完全执行,你不会看到颜色变化分开Thread.sleep(500);
。
在这个链接中,在段落中为什么Swing GUI冻结或锁定?,您可以理解为什么Java Swing GUI冻结,使用单个线程。
也查看这个官方链接,在创建线程一段,以及这个页面,返回:
Swing的单线程规则说Swing组件只能是由单个线程访问。这个规则适用于get和set,这个单线程被称为事件调度线程。
单线程规则很适合UI组件,因为它们倾向于以单线程方式使用大多数操作由用户发起。此外,构建线程安全组件既困难又乏味:最好不要去做如果可以避免的话。但是单线程规则有这么多好处具有深远的意义。
Swing组件通常不遵守单线程规则除非它们的所有事件都是在事件分派上发送和接收的线程。例如,属性更改事件应该在事件分发线程和模型更改事件应该被接收事件调度线程。对于基于模型的组件,如JTable和JTree,单线程规则意味着模型本身只能由事件分发线程。由于这个原因,模型的方法必须快速执行,不应该阻塞整个用户界面将无响应。
我认为上面的句子对更好地理解Swing
包非常有用。
我报告垃圾管理员的建议。
您可以从javax.swing.Timer
包中使用Timer
类。这也是一个不错的选择。
在这个问题中,trashgod报告了一些Timer
的例子。
点击这里查看Timer
的教程
根据我对你代码的理解,我可能会推荐使用SwingWorker。
我知道你没有任何昂贵的代码,但如果你使用SwingWorker,你将能够更容易地更新你的GUI。
我不确定你在这里使用的是哪个框架…但是你可能需要在Thread.sleep()之前使用repaint()。也许有Manager.gui.repaint()吗?(抱歉,完全是猜测…)