【问题标题】:Invalid Thread Access: SWT in AWT ActionListener无效的线程访问:AWT ActionListener 中的 SWT
【发布时间】:2018-04-11 18:54:14
【问题描述】:

试图摆脱这个 SWTException: Invalid thread access。从 JButton ActionListener 中生成。最终目的是让按钮打开浏览器窗口,导航到 URL,然后将 URL 带回打开对话框...

private static final Display display = Display.getDefault();

// Fired from JButton:
class ShowBrowserAction implements java.awt.event.ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {

        // Place-holder UI Update...
        display.asyncExec(new Runnable() {
            public void run() {
              System.out.println("Async task run");
            }
        });

        // Blocking until UI element is done...
        while (!display.isDisposed()) {
           // Always gives a thread access error, but still calls async event:  
           if ( !display.readAndDispatch()  )
                display.sleep();
        }

    }   
}

想法?

【问题讨论】:

  • 我可以用 try/catch 包围 readAndDispatch ,它实际上似乎非常好。但这似乎是作弊,我想以后会回来困扰我。
  • 看来,如果我将显示实例更改为 new Display() 而不是 Display.getDefault() 错误就会消失。但我不明白为什么会这样。 Display.getCurrent() 返回“null”,因此当前线程中似乎不存在活动显示...?

标签: java multithreading swt awt


【解决方案1】:

您只能在 SWT UI 线程上调用 SWT 操作。不支持在其他任何地方调用它们。

如果您想等待可运行的 UI 完成,请使用 syncExec 而不是 asyncExec

您说它似乎有效,但这在不同平台上会有所不同。例如在 macOS 上它肯定会完全失败。

【讨论】:

  • 但在上面的示例中,我实际上并没有调用任何 UI 操作,是吗? display.readAndDispatch 是唯一被调用的方法,这不是 UI 更新,对吧?
  • Display 相关的任何操作都算作 UI 操作。 readAndDispatch 将执行所有待处理的 UI 操作,因此它必须在 UI 线程中运行。 asyncExecsyncExec 是唯一的例外。
猜你喜欢
  • 1970-01-01
  • 2011-12-15
  • 1970-01-01
  • 2015-04-24
  • 2023-03-19
  • 2014-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多