我有几个关于Swing的问题,并使用EDT进行GUI更新.我刚开始读这个东西,所以我是这个领域的全新初学者:
>在EDT上运行哪些操作?如果不这样,只是提出异议?
>有没有特定的时间,我们实际上在EDT自动?
>如果我们使用SingUtilities.invoke调度任务,我们将它排队到当前的GUI更新任务队列中?
>访问上面的队列我猜想是同步的,或者是使用一些并发的集合,但是如果我安排两个GUI更新任务,从两个后台线程,不可能先说一个呢?例如,如果线程1 FIRST提交将JLable的文本设置为“yes”的任务,然后在很短的时间之后,第二个线程将出现并提交将该值设置为“否”的任务,我们是否保证结果将是“是”,还是仅仅是操作系统安排这些事情的问题?
> SwingWorker确实如何在EDT上运行done()方法?它设置以下代码:
future = new FutureTask<T>(callable) { @Override protected void done() { doneEDT(); setState(StateValue.DONE); } };
所以我想知道FutureTask是否以某种方式确保invokeLater被调用?
感谢您的所有答案.
解决方法
>一个很好的规则是所有的操作(访问/更新/ …)都应该在EDT上发生.在javadoc(某些类的某些方法)中提到了一些例外,但是很难记住,更容易坚持“在EDT上做所有事情”的方法.异常不会被提出(幸运的是,JavaFX解决了这个缺点).您可以使用自定义RepaintManager来检测大多数这些违规:请参见
this article.
>用户触发的一切都在EDT处理.例如,如果用户点击按钮,则在EDT上调用相应Action或ActionListener的actionPerformed.
>正确
>您首先安排的事情将首先执行. invokeLater调用简单地将Runnable添加到队列的末尾.稍后再次使用invokeLater稍后会在之前计划的Runnable之后添加这个新的Runnable.
>看看doneEDT的代码
>用户触发的一切都在EDT处理.例如,如果用户点击按钮,则在EDT上调用相应Action或ActionListener的actionPerformed.
>正确
>您首先安排的事情将首先执行. invokeLater调用简单地将Runnable添加到队列的末尾.稍后再次使用invokeLater稍后会在之前计划的Runnable之后添加这个新的Runnable.
>看看doneEDT的代码
private void doneEDT() { Runnable doDone = new Runnable() { public void run() { done(); } }; if (SwingUtilities.isEventDispatchThread()) { doDone.run(); } else { doSubmit.add(doDone); } }