这是一个糟糕的编程实践

时间:2012-02-02 19:26:48

标签: java multithreading swing

请考虑以下代码:

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对象?

2 个答案:

答案 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