请考虑以下代码:
public class MyClass extends javax.swing.JFrame {
private JTree jTree;
//Code ommited for clarity
public void methodCalledByAnotherThread(){
final DefaultTreeModel t = new DefaultTreeModel();
//Do some thing with t
SwingUtilities.invokeLater(new Runnable(){
public void Run(){
jTree.setModel(t);
}
});
}
}MyClass在Swing线程上创建和执行。在执行过程中,它会启动第二个线程,该线程最终将调用methodCalledByAnotherThread()。这个方法永远不会在Swing线程上被调用。
methodCalledByAnotherThread()创建了一个(本地) DefaultTreeModel对象并对其做了一些工作,但是因为这不在Swing线程上,所以无法将模型设置到jTree中,因此调用了SwingUtilities.invokeLater()。在Swing线程上执行的Runnable对象中,它将本地DefaultTreeModel t设置到JTree中。
我的问题是(我还没有实际编译和运行这段代码,所以它可能无法工作)。以上是不是很糟糕的编程实践?如果是这样,如何将在非Swing线程上创建的TreeModel设置为Swing对象?
发布于 2012-02-03 03:32:22
这看起来很好(实际上这是最好的方式)。只要//Do some thing with t不包含UI上已经显示的任何元素。
发布于 2012-02-03 03:40:55
1) don't extends javax.swing.JFrame more in Composition versus Inheritance,e.i.
2)最好是从当前的JTree实例rathen中使用getModel,而不是在运行时重新创建DefaultTreeModel,也可以使用un_know生命周期
3)正确的是你通过包装到invokeLater来添加model,最简单的方法是来自Runnable#Thread,更好的方法是来自SwingWorker,
https://stackoverflow.com/questions/9118628
复制相似问题