IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

Ouvrir une fenêtre modale alors que le parent est un JFXPanel


Sujet :

JavaFX

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Points : 491
    Points
    491
    Par défaut Ouvrir une fenêtre modale alors que le parent est un JFXPanel
    Bonjour,

    Il y a quelque temps j'ai demandé comment ouvrir une fenêtre modale.
    Il suffisait de retrouver le stage "parent" comme dans le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    final Window parent = monBouton.getScene().getWindow();
    [...]
    dialogStage.initOwner(parent);
    J'avais testé avec succès dans une application 100 % FX.

    Malheureusement, cela n'a pas l'air possible quand la fenêtre parent est un JFXPanel (intégré dans Swing).
    Cela génère l'erreur suivante:
    Unsupported type of owner com.sun.javafx.tk.quantum.EmbeddedStage
    Y-a-t-il une solution pour ouvrir un popup modal sur base d'un JFXPanel ?

    Merci d'avance.

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Croa, du code, croa...

    Bon, ceci dit on peut faire ça mais c'est pas parfait (quand on donne le focus a la fenêtre Swing, le dialogue ne le récupère pas) mais c'est déjà ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public class Main {
        public static void main(String... args) {
            SwingUtilities.invokeLater(Main::launchSwingApp);        
        }
     
        private static void launchSwingApp() {
            final JFrame frame = new JFrame("MyFame");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 500);
            final JFXPanel fxPanel = new JFXPanel();
            Platform.runLater(() -> createFXUI(fxPanel));
            frame.setContentPane(fxPanel);
            frame.setVisible(true);                
        }
     
        private static void createFXUI(final JFXPanel host) {
            final Button button = new Button("Salue !");
            button.setOnAction(actionEvent -> {
                final Stage dialog = new Stage();
                dialog.setTitle("MyDialog");
                dialog.initStyle(StageStyle.UTILITY);
                dialog.initModality(Modality.APPLICATION_MODAL);
                dialog.setAlwaysOnTop(true);
                dialog.show();
            });
            final StackPane root = new StackPane();
            root.getChildren().add(button);
            final Scene scene = new Scene(root);
            host.setScene(scene);
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Points : 491
    Points
    491
    Par défaut
    Merci Bouye pour ta réponse. Malheureusement le setAlwaysOnTop n'existe pas en FX2.2.

    Bon ben je vais coller une solution qui me semble parfaite, et que n'ai trouvée nulle part ailleurs.

    Ma fenêtre est modale et le code s'exécute à la fermeture, que demander d'autre...

    Maintenant comme ça manipule des thread qui est une notion que je ne maitrise pas vraiment, je suis ouvert à tous vos commentaires

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    //ouvre popup 
    	@FXML
    	private void handleOpenTerminMngt() throws IOException
    	{
    		asyncDialog = createModalDialog("Mon Titre");
    		createScene();
    	}
     
    	private JDialog  asyncDialog;
    	private JFXPanel jfxPanel = new JFXPanel();
     
     
    	private JDialog createModalDialog(String title) 
        {
        	final JDialog dialog = new JDialog();
        	JButton btnOk = new JButton("Ok");
     
        	btnOk = IconButtonFactory.getButton(myConstants.BTN_OK);
        	btnOk.addActionListener(new java.awt.event.ActionListener()
            {
    			@Override
    			public void actionPerformed(java.awt.event.ActionEvent e)
    			{
    				asyncDialog.dispose();
    			}
            });
     
        	btnOk.setSize(50,50);
     
        	jfxPanel = new JFXPanel();
     
        	JPanel btnBar = new JPanel(new BorderLayout(5, 0));
        	btnBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
        	btnBar.add(btnOk, BorderLayout.EAST);
     
        	dialog.setLayout(new BorderLayout());
        	dialog.add(jfxPanel, BorderLayout.CENTER);
        	dialog.add(btnBar, BorderLayout.SOUTH);
            dialog.setPreferredSize(new Dimension(600, 600));
            dialog.setTitle(title);
            dialog.setModal(true);
            dialog.setAlwaysOnTop(true);
            dialog.pack();
            dialog.setLocationRelativeTo(this);
     
            Runnable dialogDisplayThread = new Runnable() 
            {
                public void run() 
                {
                	dialog.setVisible(true);
                	//ici le code après la fermeture du popup
                	System.err.println("Code après fermeture");
                }};
     
            new Thread(dialogDisplayThread).start();
     
            while(!dialog.isVisible())
            {/*Busy wait*/}
            dialog.paint(dialog.getGraphics());
            return dialog;
        }
     
        private void createScene() 
        {
     
        	Platform.runLater(new Runnable() 
        	{
                @Override
                public void run() 
                {
                	initFX();
                }
            });
        }
     
    	private  void initFX() 
    	{
            // This method is invoked on the JavaFX thread
    		try
    		{	
        		String fxmlPath =  "newmod/gui/TerminCrud.fxml";
     
    			FXMLLoader fxmlLoader = new FXMLLoader(getClass().getClassLoader().getResource("monChemin" + fxmlPath));   
    			Parent root = (Parent)fxmlLoader.load(); 
    			Scene  scene  =  new  Scene(root,255,255);
    			jfxPanel.setScene(scene);
    		}
        	catch (IOException e)
        	{
    			e.printStackTrace();
    		}
        }

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Hum, je ne comprends pas vraiment ce que tu cherches a faire avec ce bloc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Runnable dialogDisplayThread = new Runnable() {
        public void run() {
            dialog.setVisible(true);
            //ici le code après la fermeture du popup
            System.err.println("Code après fermeture");
        }
    };
    new Thread(dialogDisplayThread).start();
    while (!dialog.isVisible()) {/*Busy wait*/
    }
    dialog.paint(dialog.getGraphics());
    Surtout le Busy wait qui est vraiment MAL.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Mouai bon, un jour vous comprendrez l’utilité de faire des mini-micro programmes de tests A COTE du gros projet, histoire de tester des trucs (et de pouvoir poster le code en case de besoin) avant de porter les modifs vers le gros projet.

    Donc, en se basant sur le bout de code non-réutilisables postés et après quelques test :

    Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <?xml version="1.0" encoding="UTF-8"?>
     
    <?import java.lang.*?>
    <?import java.util.*?>
    <?import javafx.scene.*?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.*?>
     
    <StackPane id="root" fx:id="root" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.Main2">
        <Button text="Click me!" onAction="#handleOpenTerminMngt" />
    </StackPane>

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    package test;
     
    public interface FXCreator extends Runnable {    
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    package test;
     
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import java.io.IOException;
    import java.net.URL;
    import java.util.ResourceBundle;
    import javafx.application.Platform;
    import javafx.embed.swing.JFXPanel;
    import javafx.fxml.FXML;
    import javafx.fxml.FXMLLoader;
    import javafx.fxml.Initializable;
    import javafx.scene.Parent;
    import javafx.scene.Scene;
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import org.scenicview.ScenicView;
     
    public class Main2 extends JFrame implements Initializable {
     
        @FXML
        private Parent root;
     
        public Main2() {
            // This method is invoked on the JavaFX thread (see main, the thread which loaded the FXML).
            super("MyFame");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
     
        @Override
        public void initialize(URL location, ResourceBundle resources) {
            // This method is invoked on the JavaFX thread
            final Scene scene = new Scene(root);
            final JFXPanel host = new JFXPanel();
            host.setScene(scene);
            ScenicView.show(scene);
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    // This method is invoked on the EDT.
                    setContentPane(host);
                    setSize(500, 500);
                    setVisible(true);
                }
            });
        }
     
        public static void main(String... args) {
            // Only needed to the test case, initializes JFX toolkit.
            new JFXPanel();
            Platform.runLater(new Runnable() {
                public void run() {
                    try {
                        // This method is invoked on the JavaFX thread (not sure it is needed).
                        final String fxmlPath = "test.fxml";
                        final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(fxmlPath));
                        fxmlLoader.load();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
     
        //ouvre popup 
        @FXML
        private void handleOpenTerminMngt() throws IOException {
            // This method is invoked on the JavaFX thread
            createModalDialog("Mon Titre", new FXCreator() {
                @Override
                public void run() {
                    initFX(jfxPanel);
                }
            });
        }
     
        private final JFXPanel jfxPanel = new JFXPanel();
     
        private void createModalDialog(String title, FXCreator creator) {
            if (!SwingUtilities.isEventDispatchThread()) {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        // This method is invoked on the EDT.
                        createModalDialog(title, creator);
                    }
                });
                return;
            }
            // This part of the method is invoked on the EDT.
            final JDialog dialog = new JDialog();
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            final JButton btnOk = new JButton("Ok");
    //         btnOk = IconButtonFactory.getButton(myConstants.BTN_OK);
            btnOk.addActionListener(new java.awt.event.ActionListener() {
                @Override
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    // This method is invoked on the EDT.
                    dialog.setVisible(false);
                }
            });
            btnOk.setSize(50, 50);
            final JPanel btnBar = new JPanel(new BorderLayout(5, 0));
            btnBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5));
            btnBar.add(btnOk, BorderLayout.EAST);
            dialog.setLayout(new BorderLayout());
            dialog.add(jfxPanel, BorderLayout.CENTER);
            dialog.add(btnBar, BorderLayout.SOUTH);
            dialog.setPreferredSize(new Dimension(600, 600));
            dialog.setTitle(title);
            dialog.setModal(true);
            dialog.setAlwaysOnTop(true);
            dialog.pack();
            dialog.setLocationRelativeTo(this);
            dialog.addWindowListener(new WindowAdapter() {
                @Override
                public void windowOpened(WindowEvent e) {
                    // This method is invoked on the EDT.
                    if (creator != null) {
                        Platform.runLater(creator);
                    }
                }
            });
            dialog.setVisible(true);
        }
     
        private void initFX(final JFXPanel host) {
            // This method is invoked on the JavaFX thread
            try {
                final String fxmlPath = "TerminCrud.fxml";
                final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(fxmlPath));
                final Parent root = (Parent) fxmlLoader.load();
                final Scene scene = new Scene(root, 255, 255);
                host.setScene(scene);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    Il va de soit que certains trucs qui peuvent avoir l'air un peu bizarre ici (genre l'interface vide qui étend Runnable) prennent tout leur sens avec les lambdas et le JDK 8 (qui rend aussi la chose beaucoup moins verbeuse).
    Le but etant bien sur de trouver une méthode générique pour initialiser de tels boites de dialogues mi-FX mi-Swing qu'on pourra ensuite placer dans une fabrique qui va pouvoir être réutiliser dans divers endroits du programme.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    876
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Novembre 2005
    Messages : 876
    Points : 491
    Points
    491
    Par défaut
    Merci pour ton code, ça marche aussi et sans doute que c'est plus propre.

    Les deux méthodes, celle que j'avais proposée et la tienne, ont malheureusement la caractéristique de créer un super Popup qui reste toujours devant mais même devant les autres applications !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Ouvrir une fenêtre modale à l'ouverture d'une page
    Par fashion80 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 1
    Dernier message: 02/11/2012, 10h30
  2. Owner, Parent, ParentForm toujours à null poru une fenêtre modal
    Par bubulemaster dans le forum Windows Forms
    Réponses: 2
    Dernier message: 30/04/2008, 16h16
  3. Réponses: 3
    Dernier message: 30/10/2007, 15h14
  4. [VB.NET] Comment ouvrir une fenêtre modale avec Thread ?
    Par Damien10 dans le forum Windows Forms
    Réponses: 1
    Dernier message: 19/11/2006, 11h28
  5. [ SWING ] Ouvrir une fenêtre dans son parent
    Par Invité dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 12/01/2006, 16h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo