从Swing Frame

时间:2015-08-23 15:15:02

标签: java swing javafx modal-dialog

我目前正在开发一个使用基于swing的框架的项目。我的目标是为这个项目添加一个JavaFX组件,但是我遇到了模态对话框的一些问题。

总的来说,我的问题可以简化如下 -

Swing:我有一个包含按钮的JFrame。当我按下这个按钮时,我想打开一个包含一些JavaFX代码的对话框。这个新对话框应该阻止并始终位于框架的顶部。

JavaFX:这里我也有一个按钮。当我按下此按钮时,我想显示一个Alert,它应该阻止对话框(因此也会阻止Swing JFrame)。

目前我的解决方案是使用JDialog包含JFXPanel作为"胶水"总的来说我的逻辑如下

  • JFrame包含一个用于打开新JDialog
  • 的按钮
  • JDialog包含JFXPanel,其中包含一个包含JavaFX Scene
  • 的JavaFX Button
  • 按此JavaFX Button会打开Alert

代码位于这篇文章的底部。

目前JDialog按预期工作。它会阻止父框架并始终位于其上面。

另一方面,JavaFX Dialog并不像预期的那样有效。它会阻止JavaFX Scene(我无法多次按下该按钮),但它在JDialog方面存在一些问题。这些是 -

  1. 并不总是在它之上。我可以将JDialog带到警报前面
  2. 它不会阻止它。我可以使用X
  3. 关闭JDialog

    我自己的理论是问题是JDialogJFXPanel之间的关系。但我不太确定如何将它们联系起来。

    一个快速而又肮脏的例子:

    package test;
    
    import java.awt.Dialog.ModalityType;
    import java.awt.Frame;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.lang.reflect.Field;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import javafx.application.Platform;
    import javafx.embed.swing.JFXPanel;
    import javafx.event.EventHandler;
    import javafx.scene.Scene;
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.control.Button;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Modality;
    import javafx.stage.Window;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    
    
    public class TestFXInSwing {
    
    private static void createAndShowGUI() {
    
        JFrame frame = new JFrame("JFrame");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        JButton button = new JButton("Open JDialog With JFXPanel");
    
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                System.err.println("Opening JFXPanel");
    
                JDialog dialog = new JDialog(frame, "JDialog");
                final JFXPanel fxPanel = new JFXPanel();
                dialog.setModal(true);
    
                dialog.setModalityType(ModalityType.APPLICATION_MODAL);
    
                dialog.add(fxPanel);
    
                Platform.setImplicitExit(false);
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        initFX(fxPanel);
                    }
    
                    private void initFX(JFXPanel fxPanel) {
                        Button btn = new Button("Open JavaFX Alert");
    
                        btn.setOnAction(new EventHandler<javafx.event.ActionEvent>() {
    
                            @Override
                            public void handle(javafx.event.ActionEvent t) {
                                System.err.println("Javafx button pressed");
    
                                Alert alert = new Alert(AlertType.INFORMATION);
                                alert.setTitle("Javafx Alert");
                                alert.setHeaderText("Look, an Information Dialog");
                                alert.setContentText("I have a great message for you!");
                                alert.initModality(Modality.APPLICATION_MODAL);
    
                                Field f;
                                try {
                                    f = JFXPanel.class.getDeclaredField("stage");
                                    f.setAccessible(true);
                                    alert.initOwner((Window) f.get(fxPanel));
                                } catch (NoSuchFieldException ex) {
                                    Logger.getLogger(TestFXInSwing.class.getName()).log(Level.SEVERE, null, ex);
                                } catch (SecurityException ex) {
                                    Logger.getLogger(TestFXInSwing.class.getName()).log(Level.SEVERE, null, ex);
                                } catch (IllegalArgumentException ex) {
                                    Logger.getLogger(TestFXInSwing.class.getName()).log(Level.SEVERE, null, ex);
                                } catch (IllegalAccessException ex) {
                                    Logger.getLogger(TestFXInSwing.class.getName()).log(Level.SEVERE, null, ex);
                                }
                                alert.showAndWait();
                            }
                        });
    
                        StackPane root = new StackPane();
                        root.getChildren().add(btn);
    
                        Scene scene = new Scene(root, 500, 500);
                        fxPanel.setScene(scene);
                    }
                });
    
                dialog.setVisible(true);
            }
    
        });
    
        frame.getContentPane().add(button);
    
        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }
    
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
    }
    

0 个答案:

没有答案