2013-08-23 16 views
1

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

我现在想要可视化图形,所以我检索对图形的引用并将其设置为给予VisualizationViewer的布局。当更新进入时,它们在另一个线程中处理,然后我调用VisualizationViewer.repaint()刷新图形。

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

感谢

回答

0

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

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

我通过在保存VisualizationViewerJPanel上添加PropertyChangeListener来实现此目的。这将监听图中的更改并相应地调用重新绘制。

+0

您正在说我正在说的,更新GUI必须除了在你的答案中,你保留了'repaint',GUI更新,在EDT上,这是不理想的...只是改变EDT上的标签,或者例如在EDT上添加顶点。 –

+0

这正是我所期待的。谢谢! – Smitty

+0

现在我对Jon的评论有些困惑。 – Smitty

0

大多数GUI更新必须在EDT来完成。最好直接对其进行更改,并避免拨打repaint,除非这是绝对必要的。

就一定要更新GUI代码呼吁EDT,你能做到这一点还挺代码:

final JLabel label = yourLabel; 
Runnable code = new Runnable() { 

    @Override 
    public void run() { 
    label.setText("SomeText");  
    } 
}; 

if (SwingUtilities.isEventDispatchThread()) { 
    code.run(); 
} else { 
    SwingUtilities.invokeLater(code); 
} 

这样一来,您不必担心来自哪个线程代码从中调用,它将更新标签。

编辑: 为了澄清,你可以做什么,当你想更新你的图形,是确保把电话转到您VisualizationViewerrepaint方法是这样

final VisualizationViewer viewer = w; 
Runnable code = new Runnable() { 

    @Override 
    public void run() { 
    viewer.repaint();  
    } 
}; 

if (SwingUtilities.isEventDispatchThread()) { 
    code.run(); 
} else { 
    SwingUtilities.invokeLater(code); 
} 
+0

当我创建GUI时,将引用返回给图仍然可以,但只要确保在更新图之后在EDT上使用invokeLater执行该操作就可以了。 – Smitty

+0

是的,只要它在EDT上完成。我仍然建议避免使用'repaint',因为它不仅仅是所需的更改。 –

+0

我想我现在明白你的意思了。在更新EDT中的东西后,它会刷新退出可运行时所需的东西吗?所以通过改变EDT上的东西更好,因为调用'repaint'确实不需要很多额外的东西? – Smitty

相关问题