我试图创建一个模态对话框,要求用户输入。我的程序使用Swing来构建gui,但是由于我想用css对组件进行样式化,所以我使用的是JFXPanels而不是常规的JPanels。当我将JFXPanel添加到JFrame中时,一切正常,但如果我试图向JDialog添加JFXPanel,则JDialog不会显示任何内容。
我正在使用JDK 11。
我在这里错过了什么?
这是我的代码:
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);
});
}
}发布于 2022-06-25 14:12:20
下面的代码是一个概念证明。
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);
}
}注意,在上面的代码中,这一行将阻塞(即不会返回),直到JDialog关闭。
fxDlg.setVisible(true);还请记住,Swing代码必须在事件调度线程 (EDT)上运行,JavaFX代码必须在JavaFX应用程序线程上运行。
在编写上述代码时,我参考了以下网页。
https://stackoverflow.com/questions/72754036
复制相似问题