请考虑以下代码:
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
因此调用{ {1}}。在Swing线程上执行的Runnable对象中,它将LOCAL SwingUtilities.invokeLater()
t设置为DefaultTreeModel
。
我的问题是(我实际上还没有编译和运行此代码,所以它可能无效)..是上面的BAD编程实践?如果是这样,我如何将在非Swing线程上创建的JTree
设置为Swing对象?
答案 0 :(得分:3)
看起来很好(事实上它是最好的方法)。只要//Do some thing with t
不包含已在UI上显示的任何元素。
答案 1 :(得分:3)
1)在Composition versus Inheritance,e.i。
中不要extends javax.swing.JFrame
多
2)更好的是来自currnet getModel
实例的JTree
而不是在运行时重新创建DefaultTreeModel
并且可能具有un_know生命周期
3)正确的是,您通过换入model
添加invokeLater
,最简单的消息来自Runnable#Thread
,最好来自SwingWorker
,