我如何在同一线程中使用 SWT Shell 和 JavaFx 阶段?

How can i use SWT Shells and JavaFx stages in the same Thread?

我有一个带有 JavaFX Stage 和 SWT 的应用程序 Shell。 JavaFX 阶段中有一些控件可以更改 Shell 中 SWT 小部件的属性,还有一些 JaveFX 控件可以通知 SWT 小部件中的更改。 当然,JavaFX 的一切都必须在 JavaFx 应用程序线程中发生,而 SWT 小部件的一切都必须在 SWT 线程中发生。

我首先尝试为每个线程设置一个线程,并在切换上下文时切换线程。这很烦人,我决定不再采用这种方法。 相反,在 JavaFX 应用程序线程内创建 SWT window,以便两个 UI 运行 在同一线程上。除了一件事

while (!shell.isDisposed()) {
    if (!display.readAndDispatch())
        display.sleep();
}

SWT 需要这个片段,否则没有任何小部件对事件做出反应,SWT 也需要这个像其他所有东西一样在同一个线程上。但是这个片段是阻塞的,所以我一使用它,JavaFX 就会冻结。

我知道使用 SWT 和 JavaFX windows 可能是一个非常奇怪的用例,但是有解决方案吗?

澄清一下:

SWT 和JavaFX 可以在同一个线程中运行。实现这一点的一个小技巧是在调用任何其他 JavaFX 代码之前创建一个虚拟 FXCanvas 实例。 FXCanvas 通常用于将 FX 控件嵌入到 SWT 中;即使您不需要它,FXCanvas 构造函数也会正确初始化 JavaFX 以在 SWT 互操作模式下工作。

下面的代码片段演示了 SWT shell 和 JavaFX 阶段的协同工作。 SWT 和 JavaFX 按钮单击处理程序都在 JavaFX 应用程序线程上执行。

    public static void main(String[] args) {
        Display display = Display.getDefault();
        new FXCanvas(new Shell(), SWT.NONE);

        Stage primaryStage = new Stage();
        Button fxbutton = new Button("JavaFX button");
        Scene scene = new Scene(fxbutton);
        fxbutton.addEventHandler(MouseEvent.MOUSE_CLICKED, mouseEvent -> System.out.println("FX event, thread=" + Thread.currentThread().getName()));
        primaryStage.setScene(scene);
        primaryStage.show();


        Shell shell = new Shell(display, SWT.CLOSE);
        shell.setLayout(new FillLayout());
        org.eclipse.swt.widgets.Button swtbutton = new org.eclipse.swt.widgets.Button(shell, SWT.PUSH);
        swtbutton.setText("SWT button");
        swtbutton.addListener(SWT.Selection, event -> System.out.println("SWT event, thread=" + Thread.currentThread().getName()));
        shell.open();
        shell.pack();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
    }