Java Swing - 在EDT上运行

Bob*_*r02 10 java swing event-dispatch-thread

关于Swing和使用EDT进行GUI更新,我有几个问题.我刚刚开始阅读这些内容,所以我是这个领域的初学者:

  1. 在EDT上运行需要哪些操作?如果他们不这样做,只是提出一个例外?
  2. 我们实际上在EDT上有没有特定的时间?
  3. 如果我们使用我们安排任务SwingUtilities.invokeLater我们将它排入GUI更新任务的当前队列对吗?
  4. 访问上面的队列我猜是同步的,或者使用了一些并发集合,但是如果我从两个后台线程调度两个GUI更新任务,就不可能说先添加哪一个?例如,如果线程1 FIRST提交将JLable的文本设置为"是"的任务,然后,短时间之后,第二个线程出现并提交将该值设置为"no"的任务,我们是否保证结果将是"是",或者仅仅是操作系统如何安排这些事情的问题?
  5. SwingWorker究竟是如何确保done()在EDT上运行该方法的?它设置以下代码:

      future = new FutureTask<T>(callable) {
                   @Override
                   protected void done() {
                       doneEDT();
                       setState(StateValue.DONE);
                   }
               };
    
    Run Code Online (Sandbox Code Playgroud)

所以我想知道FutureTask是否以某种方式确保invokeLater被调用?

谢谢你的所有答案.

Rob*_*bin 16

  1. 一个好的规则是所有操作(访问/更新/ ......)都应该在EDT上进行.javadoc中提到了一些例外(某些类的某些方法),但它们很难记住,更容易坚持"在EDT上做所有事情"的方法.不会例外(幸运的是,JavaFX解决了这个缺点).您可以使用自定义RepaintManager来检测大多数违规行为:请参阅此文章.
  2. 用户触发的所有内容都在EDT上处理.例如,如果用户点击一个按钮,actionPerformed则相应的ActionActionListener将在EDT上调用.
  3. 正确
  4. 您首先安排的事情将首先执行.该invokeLater调用只是Runnable在队列末尾添加.invokeLater稍后使用第二次将Runnable在先前安排的之后添加新的Runnable.
  5. 看看代码 doneEDT

    private void doneEDT() {
        Runnable doDone = 
            new Runnable() {
                public void run() {
                    done();
                }
            };
        if (SwingUtilities.isEventDispatchThread()) {
            doDone.run();
        } else {
            doSubmit.add(doDone);
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)


JB *_*zet 8

  1. 基本上,每次使用Swing组件或Swing组件的模型时,都必须在EDT中完成.如果不这样做,则不会引发任何例外.它可以工作,但它也可能无法工作,行为不稳定,数据损坏等.
  2. 每个Swing事件监听器都在EDT中调用.基本上,除了main方法之外,Swing应用程序的每一行代码都默认在EDT中执行,除非您明确地启动一个线程,使用SwingWorker或类似的东西.
  3. 是.
  4. 提交给SwingUtilities.invokeLater()的任务按照与提交顺序相同的顺序执行.
  5. 在内部,它使用SwingUtilities.invokeLater()或类似的方法.FutureTask与Swing没有任何关系.SwingWorker确保在EDT中执行其done方法.该doneEDT()方法具有以下注释:在EDT上完成调用.