javafx 和swing_Swing和JavaFX:使用JFXPanel

本文介绍了如何在Swing应用中使用JavaFX的JFXPanel组件,通过示例展示了如何创建含有JavaFX控件的Swing面板,并强调了所有JavaFX组件的操作必须在JavaFX Application线程中进行。同时,文章讨论了简化FX线程处理的可能性。

javafx 和swing

我很快将不得不在基于Swing的胖客户端中处理JavaFX –哦,对不起,我的意思是“多层富客户端”!

因此,这使我来看看JFXPanelJFXPanel是一个javax.swing.JComponent,用于将JavaFX内容嵌入到Swing-UI中。 JFXPanel的用法类似于JPanel,并且可以通过EDT作为通用Swing组件进行访问,除了必须通过JavaFX应用程序线程来处理JavaFX组件之外。

为了解决这些问题,我创建了两个类似的面板(Swing + JavaFX),每个面板都有一个按钮,一个TextField和一个Label,并将它们放置在JSplitPane和JFrame中:

仔细看里面

要尝试Swing <-> JavaFX互操作性,按钮操作是将文本从TextField设置为JLabel,反之亦然。
JPanel处理通用的Swing东西没有什么特别的,但是JFXPanel包含JavaFX控件:

public class SwingFXPanel extends JFXPanel {

    private Button testButton;
    private TextField testTextField;
    private Label testLabel;
    private VBox pane;

    public SwingFXPanel() {
        init();
    }

    private void init() {
        testButton = new Button("I am a JavaFX Button");
        testTextField = new TextField();
        testLabel = new Label("empty");
        pane = new VBox();
        pane.setAlignment(Pos.CENTER);
        pane.getChildren().addAll(testTextField, testButton, testLabel);
        Platform.runLater(this::createScene);
    }

    private void createScene() {
        Scene scene = new Scene(pane);
        setScene(scene);
    }

    public Button getTestButton() {
        return testButton;
    }

    public TextField getTestTextField() {
        return testTextField;
    }

    public Label getTestLabel() {
        return testLabel;
    }
}

这里很重要:将场景添加到JavaFX Application线程内的JFXPanel:

Platform.runLater(this::createScene);

如果您致电:

createScene()

从另一个线程,您会获得Runtime-Exception:

java.lang.IllegalStateException: Not on FX application thread; currentThread = AWT-EventQueue-0

同样,每次与JavaFX相关内容的交互都必须放在JavaFX Application Thread上:

例如:
Platform.runLater(() -> {
   swingFXPanel.getTestLabel().setText(swingPanel.getTestTextField().getText());
});
public class InteropFrame extends JFrame {

    private JSplitPane centralSplitPane;
    private SwingPanel swingPanel;
    private SwingFXPanel swingFXPanel;

    public InteropFrame(){
        init();
    }

    private void init() {
        setTitle("Swing <-> JavaFX Interoperatbiliy");
        setSize(500, 500);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        centralSplitPane = new JSplitPane();
        centralSplitPane.setDividerLocation(0.5);
        centralSplitPane.setResizeWeight(0.3);
        
        swingPanel = new SwingPanel();
        swingFXPanel = new SwingFXPanel();

        swingPanel.getTestButton().addActionListener((ActionEvent e) -> {
            Platform.runLater(() -> {
                swingFXPanel.getTestLabel().setText(swingPanel.getTestTextField().getText());
            });
        });


        swingFXPanel.getTestButton().setOnAction((javafx.event.ActionEvent t) -> {
            swingPanel.getTestLabel().setText(swingFXPanel.getTestTextField().getText());
        });

        centralSplitPane.setLeftComponent(swingPanel);
        centralSplitPane.setRightComponent(swingFXPanel);

        add(centralSplitPane, BorderLayout.CENTER);
    }
}

另外,处理FXML也很简单:

public class SwingFXMLPanel extends JFXPanel {

    @FXML
    private Button testButton;
    @FXML
    private TextField testTextField;
    @FXML
    private Label testLabel;

    private VBox rootPane;

    private URL fxmlResource;
    
    public SwingFXMLPanel(URL fxmlResource){
        this.fxmlResource = fxmlResource;
        init();
    }

    private void init(){
        rootPane = new VBox();
        FXMLLoader loader = new FXMLLoader(fxmlResource);
        loader.setController(this);
        loader.setRoot(rootPane);
        try {
            loader.load();
        } catch (IOException ex) {
            Logger.getLogger(SwingFXMLPanel.class.getName()).log(Level.SEVERE, null, ex);
        }

        testButton.setText("I am a JavaFX Button");
        testLabel.setText("empty");

        Platform.runLater(this::createScene);
    }

    private void createScene() {
        Scene scene = new Scene(rootPane);
        setScene(scene);
    }

    public Button getTestButton() {
        return testButton;
    }

    public TextField getTestTextField() {
        return testTextField;
    }

    public Label getTestLabel() {
        return testLabel;
    }

}
对我来说,让我的同事尽可能多地接受在Swing中使用JavaFX至关重要。

因此,我想简化特定的FX应用程序线程处理。 因此,如果使用JPanel的主要区别只是添加以下内容,那么也许可以实现:

private void createScene() {
        Scene scene = new Scene(rootPane);
        setScene(scene);
    }

并致电:

Platform.runLater(this::createScene);

JFXPanel中

  • 您可以在此处找到完整的示例代码。

翻译自: https://www.javacodegeeks.com/2014/11/swing-and-javafx-working-with-jfxpanel.html

javafx 和swing

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值