Java Swing - 在EDT上运行 [英] Java Swing - running on EDT

查看:108
本文介绍了Java Swing - 在EDT上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a couple of questions with regards to Swing and using EDT for GUI updates. I just started reading on this stuff so I am a full beginner in this area:


  1. 在EDT上运行需要哪些操作?如果他们不这样做,只是提出一个例外?

  2. 我们实际上在EDT上是否有任何特定时间?

  3. 如果我们使用 SingUtilities.invokeLater计划任务我们将它排入GUI更新任务的当前队列吗?

  4. 访问上述队列我猜是同步的,或者使用了一些并发集合,但是如果我从两个后台线程调度两个GUI更新任务,就不可能说哪一个会先添加?例如,如果线程1 FIRST提交了将JLable的文本设置为是的任务,然后,短时间后,第二个线程出现并提交将该值设置为no的任务,我们是否保证结果将是是,或者只是操作系统如何安排这些事情?

  5. SwingWorker究竟如何确保 done()方法在EDT上运行?它设置以下代码:

  1. Which operations are required to run on the EDT? If they don't, is simply an Exception raised?
  2. Are there any specific times when we actually are on the EDT automatically?
  3. if we schedule a task using SingUtilities.invokeLater we enqueue it to the current queue of GUI update tasks right?
  4. Accesses to the above queue I guess are synchronized, or some concurrent collection is used, but if I schedule two GUI update tasks, from two background threads, it is impossible to say which one will be added first? For instance, if Thread 1 FIRST submits a task of setting the text of a JLable to either "yes", and then, short time later, second thread comes along and submits task of setting that value to "no", are we guaranteed that the result will be "yes", or is it simply a matter of how these things are scheduled by the OS?
  5. How exactly does the SwingWorker ensure that done() method is run on EDT? It sets the following code:

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


所以我想知道FutureTask是否以某种方式确定是否会调用 invokeLater

so I was wondering whether FutureTask somehow makes sure that invokeLater is called?

感谢您的所有答案。

推荐答案


  1. 一个好的规则是所有操作(访问/更新/ ......)应该在EDT上发生。 javadoc中提到了一些例外(某些类的某些方法),但它们很难记住,更容易坚持在EDT上做所有事情的方法。不会例外(幸运的是,JavaFX解决了这个缺点)。您可以使用自定义 RepaintManager 来检测大多数违规行为:请参阅这篇文章

  2. 用户触发的所有内容都在EDT上处理。例如,如果用户单击按钮,则相应 Action ActionListener的 actionPerformed 将在美国东部时间调用。

  3. 更正

  4. 首先执行您先安排的事情。 invokeLater 调用只是在队列末尾添加 Runnable 。稍后使用 invokeLater 稍后将在先前安排的 Runnable之后添加此新 Runnable

  5. 查看 doneEDT的代码

  1. A good rule is that all operations (access/updates/...) should happen on the EDT. There are a few exceptions mentioned in the javadoc (certain methods of certain classes), but they are so hard to remember that it is easier to stick to the 'do everything on the EDT' approach. Exceptions will not be raised (luckily, JavaFX fixed this shortcoming). You can use a custom RepaintManager to detect most of these violations: see this article.
  2. Everything triggered by the user is handled on the EDT. For example if the user clicks on a button, the actionPerformed of the corresponding Action or ActionListener will be called on the EDT.
  3. Correct
  4. The thing you schedule first will be executed first. The invokeLater call simply adds the Runnable at the end of the queue. Using invokeLater a second time a bit later will add this new Runnable after the previously scheduled Runnable.
  5. Take a look at the code for doneEDT

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


这篇关于Java Swing - 在EDT上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆