[英]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.