【问题标题】:Is This Bad Programming Practice这是不好的编程习惯吗
【发布时间】:2012-02-02 19:26:48
【问题描述】:

请考虑以下代码:

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 对象中,它将 LOCAL DefaultTreeModel t 设置为 JTree

我的问题是(而且我还没有真正编译和运行这段代码,所以它可能不起作用).. 上面的编程习惯是坏的吗?如果是这样,我如何将在 NON-Swing 线程上创建的 TreeModel 设置为 Swing 对象?

【问题讨论】:

    标签: java multithreading swing


    【解决方案1】:

    看起来不错(实际上这是最好的方法)。只要//Do some thing with t 不包含任何已显示在 UI 上的元素。

    【讨论】:

    【解决方案2】:

    1) 不要在Composition versus Inheritance 中添加更多extends javax.swing.JFrame,例如

    2) 最好是来自 currnet JTree 实例的 getModel,而不是在运行时重新创建 DefaultTreeModel,并且可能使用 un_know 生命周期

    3) 正确的是你添加model 通过包装成invokeLater,建议最简单的方法是从Runnable#Thread,更好的是从SwingWorker

    【讨论】:

    • 据我所知,关于您的 #2 TreeModel 不是线程安全的。因此,从另一个线程修改现有的它应该被认为是一种不好的编程习惯。
    • @ʘleg 你的considering for bad programming practice 可能是默认方式如何将 DefaultXxxModel 从后台任务添加/更新到 Swing GUI
    • 从其他线程修改非线程安全对象是默认方式不是我的问题:)
    • 我认为当前JTree中的.getModel不会返回AbstractXxxModel...
    猜你喜欢
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 2021-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多