1

我有一个不断更新的 JUNG 图(新顶点、删除顶点和更新现有顶点)。所有这些工作都是在一堆自定义类中完成的,这些类在自己的线程上运行,等待来自外部源的更新,然后进行适当的更新。

我现在想要可视化图表,因此我检索了对图表的引用并将其设置在一个布局中,该布局提供给 VisualizationViewer。当更新进来时,它们在另一个线程中处理,然后我调用 VisualizationViewer.repaint() 来刷新图形。

我的问题是,我应该做所有更新 EDT 上的图形对象的工作吗?还是可以在单独的线程中完成工作,然后像我现在一样调用 vv.repaint() ?不确定是否有用/相关,但虽然大多数更新来自外部来源,但用户仍然可以通过 GUI 手动删除图表中的内容。

谢谢

4

2 回答 2

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);
}
于 2013-08-23T12:31:04.647 回答
0

乔纳森的回答不正确,您不需要更新 EDT 上的图形对象。

VisualizationViewer应该始终在 EDT 上,是的,但是使用类似addVertexor的函数addEdge可以从任何线程调用。要记住的重要一点是,您不能vv.repaint()从正在更新的同一线程调用。

我通过PropertyChangeListenerJPanel持有的VisualizationViewer. 这会监听图表中的变化并相应地调用重绘。

于 2013-08-23T14:16:01.283 回答