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

问题描述 投票:0回答:1

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

我首先尝试为每个线程分配一个线程,并在切换上下文时切换线程。这很烦人,我决定不再采用这种方法。而是在JavaFX Application线程内创建SWT窗口,以便两个UI在同一线程上运行。除了一件事情以外,其他所有内容都可以正常工作]

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

SWT需要此代码段,否则,所有小部件都不会对事件做出反应,SWT则需要将其与其他所有对象都放在同一线程上。但是此代码段已被阻止,因此,一旦我使用它,JavaFX就会冻结。

我知道拥有SWT和JavaFX窗口可能是一个非常奇怪的用例,但是对此有解决方案吗?

仅作说明:

  • 我不希望SWT小部件内有JavaFX节点

  • 我不希望JavaFX节点内有SWT小部件。

javafx swt
1个回答
2
投票

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

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

    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();
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.