【问题标题】:java SwingWorker.doInBackground() must not access GUI elementsjava SwingWorker.doInBackground() 不能访问 GUI 元素
【发布时间】:2012-02-17 12:05:45
【问题描述】:

这可能是微不足道的,我很难理解SwingWorker 上的简单文档。

这是复制粘贴的内容

工作流程

SwingWorker 的生命周期涉及三个线程:

当前线程:在该线程上调用了 execute() 方法。它 安排 SwingWorker 在工作线程上执行并返回 立即地。可以等待 SwingWorker 完成使用 获取方法。

工作线程:在该线程上调用 doInBackground() 方法。 这是所有后台活动都应该发生的地方。通知 关于绑定属性更改的 PropertyChangeListeners 使用 firePropertyChange 和 getPropertyChangeSupport() 方法。默认 有两个可用的绑定属性:状态和进度。

事件调度线程:所有与 Swing 相关的活动都发生在此 线。 SwingWorker 调用 process 和 done() 方法, 通知此线程上的任何 PropertyChangeListener。

通常,当前线程是事件调度线程。

--

工作线程不是 EDT,因此 doInBackground() 中的代码不得访问 GUI 元素。我的理解正确吗?

背景: 我们有使用 SwingWorker 的小代码,但使用 doInBackground() 创建 FileChooser 并调用 setCurrentDirectory()。我怀疑这导致我的异常与http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6637181 几乎相同(11-关闭,不是缺陷)

【问题讨论】:

    标签: java swing swingworker event-dispatch-thread


    【解决方案1】:

    是的。从后台线程 - 常规线程和SwingWorker.doInBackground 都不能修改 UI 以避免各种麻烦。

    相反,将更改包装在 Runnable 中,并通过 SwingUtilities.invokeAndWaitSwingUtilities.invokeLater 或 - 使用 SwingWorker 时 - 通过 publish(来自 doInBackground)在 EDT 中执行。在 EDT 执行的 SwingWorkerprocess 方法中,您可以访问 GUI。

    http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html

    就我个人而言,我发现invokeLaterinvokeAndWait 在许多情况下更易于使用。 SwingWorker 适用于例如进度条。

    【讨论】:

    • 谢谢-我们几乎在所有地方都按照您在回答中写的内容进行操作。有些地方的代码使用了 swingworker。即使在这种情况下,处理也可以分为 GUI 访问和非 GUI 部分。
    • 做正确的拆分通常会提高性能,避免问题,所以强烈推荐。
    • @Jayan 教程谈论发布/处理/完成的输出,您可以测试 if(isEventDispatchThread) 请阅读stackoverflow.com/questions/7053865/…。 +1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多