简体   繁体   English

将 JFXPanel 添加到 JDialog

[英]Add JFXPanel to JDialog

I am trying to create a modal dialog that asks user for input.我正在尝试创建一个询问用户输入的模式对话框。 My program uses Swing for building gui but since i want to style my components with css i am using JFXPanels instead of regular JPanels.我的程序使用 Swing 来构建 gui,但是因为我想用 css 设置我的组件的样式,所以我使用 JFXPanels 而不是常规的 JPanels。 When i add a JFXPanel to a JFrame everything works fine, but if i try to add a JFXPanel to a JDialog, the JDialog does not show any content.当我将 JFXPanel 添加到 JFrame 时,一切正常,但是如果我尝试将 JFXPanel 添加到 JDialog,则 JDialog 不会显示任何内容。

I am using JDK 11.我正在使用 JDK 11。

What am i missing here?我在这里想念什么?

Here is my code:这是我的代码:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Optional;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;

public class JDialogExample {

    private Optional<String> output = Optional.empty();
    private final StackPane stackPane = new StackPane();
    private final JFXPanel panel = new JFXPanel();
    private final JDialog dialog = getNewJDialog();
    private final TextField tf = new TextField();

    public JDialogExample() {
        ObservableList list = stackPane.getChildren();
        list.addAll(new Label("My Label"), tf, getSubmitButton());
        panel.setScene(new Scene(stackPane));
        dialog.add(panel);
        dialog.pack();
        dialog.setLocationRelativeTo(null);
        dialog.setVisible(true);
    }

    public Optional<String> show() {
        return output;
    }

    private Button getSubmitButton() {
        Button btn = new Button();
        btn.setText("Submit");
        btn.setOnAction(new EventHandler<>() {
            @Override
            public void handle(javafx.event.ActionEvent t) {
                output = Optional.of(tf.getText());
                dialog.setVisible(false);
            }
        });
        return btn;
    }

    protected JDialog getNewJDialog() {
        return new JDialog(new JFrame(), "My dialog", true);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Platform.startup(()
                -> {
                        JFrame frame1 = new JFrame();
                        JButton b = new JButton("This works");
                        b.addActionListener(new ActionListener() {
                            @Override
                            public void actionPerformed(ActionEvent e) {
                                JDialogExample example = new JDialogExample();
                                Optional<String> userInputOptional = example.show();
                                if (userInputOptional.isPresent()) {
                                    System.out.println(userInputOptional.get());
                                }
                            }
                        });
                        frame1.add(b);
                        frame1.pack();
                        frame1.setVisible(true);
                        
                        JFrame frame2 = new JFrame();
                        StackPane stackPane2 = new StackPane();
                        JFXPanel jFXPanel = new JFXPanel();
                        Button b2 = new Button("This DOES NOT work");
                        b2.setOnAction(new EventHandler<>() {
                            @Override
                            public void handle(javafx.event.ActionEvent t) {
                                JDialogExample example = new JDialogExample();
                                Optional<String> userInputOptional = example.show();
                                if (userInputOptional.isPresent()) {
                                    System.out.println(userInputOptional.get());
                                }
                            }
                        });
                        ObservableList list2 = stackPane2.getChildren();
                        list2.addAll(b2);
                        jFXPanel.setScene(new Scene(stackPane2));
                        frame2.add(jFXPanel);
                        frame2.pack();
                        frame2.setLocationRelativeTo(null);
                        frame2.setVisible(true);
        });
    }

}

The below code is a proof of concept .下面的代码是一个概念证明

import java.awt.Dimension;
import java.awt.EventQueue;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;

public class JfxSwing {
    private FxDialog  fxDlg;
    private JFrame  frame;

    private void createAndDisplayGui() {
        frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton button = new JButton("Show Dlg");
        button.addActionListener(this::showDialog);
        frame.add(button);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private void showDialog(java.awt.event.ActionEvent event) {
        if (fxDlg == null) {
            fxDlg = new FxDialog(frame);
            fxDlg.pack();
        }
        fxDlg.setVisible(true);
        String str = fxDlg.getText();
        System.out.printf("^%s^ [Length: %d]%n", str, (str != null ? str.length() : -1));
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new JfxSwing().createAndDisplayGui());
    }
}


class FxDialog extends JDialog {
    private JFXPanel  fxPanel;
    private String  text;

    public FxDialog(JFrame owner) {
        super(owner, "FxDlg", true);
        fxPanel = new JFXPanel();
        fxPanel.setPreferredSize(new Dimension(100, 100));
        add(fxPanel);
        Platform.runLater(this::initFx);
        setLocationRelativeTo(owner);
    }

    public String getText() {
        return text;
    }

    private void initFx() {
        TextField tf = new TextField();
        Button submit = new Button("Submit");
        submit.setOnAction(e -> {
            text = tf.getText();
            EventQueue.invokeLater(() -> setVisible(false));
        });
        VBox root = new VBox(10.0d);
        root.getChildren().addAll(new Label("My Label"), tf, submit);
        Scene scene = new Scene(root);
        fxPanel.setScene(scene);
    }
}

Note that this line, in the above code, will block (ie will not return) until the JDialog is closed.请注意,上述代码中的这一行将阻塞(即不会返回),直到JDialog关闭。

fxDlg.setVisible(true);

Also remember that Swing code must run on the Event Dispatch Thread (EDT) and JavaFX code must run on the JavaFX application thread.还要记住, Swing代码必须在事件调度线程(EDT) 上运行,而 JavaFX 代码必须在 JavaFX 应用程序线程上运行。

I referred to the following Web page when writing the above code.在编写上述代码时,我参考了以下网页。
Integrating JavaFX into Swing Applications 将 JavaFX 集成到 Swing 应用程序中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM