我有一个不断更新的JUNG图(新顶点,删除顶点和更新现有顶点)。所有这些工作都是在一堆自定义类中完成的,这些类在自己的线程上运行,等待来自外部源的更新,然后进行适当的更新。
我现在想要将图形可视化,因此我检索对图形的引用并将其设置在给予VisualizationViewer的布局中。当更新进入时,它们在另一个线程中处理,然后我调用VisualizationViewer.repaint()来刷新图形。
我的问题是,我是否应该在EDT上更新图形对象的所有工作?或者可以在单独的线程中完成工作,然后像我现在一样调用vv.repaint()?不确定是否有用/相关,但是大多数更新来自外部源,用户仍然可以通过GUI手动删除图形中的内容。
由于
答案 0 :(得分:0)
大多数GUI更新必须在EDT上完成。最好直接对其进行更改并避免调用repaint
,除非绝对必要。
为确保在EDT上调用更新GUI的代码,您可以执行以下代码:
final JLabel label = yourLabel;
Runnable code = new Runnable() {
@Override
public void run() {
label.setText("SomeText");
}
};
if (SwingUtilities.isEventDispatchThread()) {
code.run();
} else {
SwingUtilities.invokeLater(code);
}
这样,你不必担心从哪个线程调用代码,它会更新标签。
编辑:
为了澄清,您可以做的是,当您想要更新图表时,确保调用VisualizationViewer
repaint
方法就像这样完成
final VisualizationViewer viewer = w;
Runnable code = new Runnable() {
@Override
public void run() {
viewer.repaint();
}
};
if (SwingUtilities.isEventDispatchThread()) {
code.run();
} else {
SwingUtilities.invokeLater(code);
}
答案 1 :(得分:0)
Jonathan的回答不正确,你不需要在EDT上更新图形对象。
您的VisualizationViewer
应该始终在EDT上,是的,但是可以从任何线程调用addVertex
或addEdge
等函数。要记住的重要一点是,您无法从正在更新的同一个线程中调用vv.repaint()
。
我通过在PropertyChangeListener
上添加JPanel
来保持VisualizationViewer
来实现这一目标。这会监听图表中的更改并相应地调用重绘。