Partage
  • Partager sur Facebook
  • Partager sur Twitter

Petite problème.

Enchainement de plusieurs JDialog.

Sujet résolu
    31 mars 2009 à 19:45:29

    Salut, donc voilà, j'ai un petit soucis, en fait j'fais une appli qui a besoin de demander des infos à l'utilisateur, alors j'utilise des JDialog, et je fais une première JDialog qui demande une info à l'utilisateur, et ensuite en fonction de cette info j'ai une autre JDialog qui doit s'afficher après.
    Le problème survins après que j'ai encoder la première info, en fait l'exécution continue et donc, quand j'ai encoder la première info, il ne m'affiche pas la seconde JDialog.

    J'aimerais en fait que le programme attendent que l'utilisateur est validé l'info dans la JDialog1 avant que la deuxième JDialog s'affiche.

    J'ai essayer la méthode wait sur la première JDialog, en me disant que swing crée un thread lors de l'affichage des composants, et quand j'ai validé les information de la première fenêtre, j'apelle notify() pour déverrouiller le Thread main et faire afficher la deuxième JDialog, mais ça ne fonctionne pas, en plus j'ai une erreur quand j'appelle wait ().

    Quelqu'un aurait t'il un solution ?
    Merci d'avance.

    Voici en gros ce que donne le code :

    else if (nameAction.equals("ShowAddMediaDialog")) {
    		OptionDialog jod = OptionDialog.createSelectTypeOfMediaDialog(this, cstartpagecontroler);
    		jod.showDialog();
    	try {
                    jod.wait ();
            } catch (InterruptedException e) {
                    e.printStackTrace ();
            }  
            OptionDialog jod2 = OptionDialog.createSelectTypeOfMediaDialog(this,   cstartpagecontroler);
    	jod2.showDialog();             
    }
    


    Et dans la classe OptionDialog :
    else if (type == TYPE_MEDIA_CHOOSER) {
    	for (int i = 0; i < jr.length; i++) {
    		if (jr[i].isSelected ()) {
    		try {							
    			typeMedia =        MediaType.class.getField(jr[i].getText()).getInt(null);							
    		} catch (IllegalArgumentException e) {
    			e.printStackTrace();
    		} catch (IllegalAccessException e) {
    			e.printStackTrace();
    		} catch (SecurityException e) {					
    		e.printStackTrace();
    		} catch (NoSuchFieldException e) {							
    			e.printStackTrace();
    		}
    	}
            notify ();					
    }
    


    Ces deux bout de codes sont dans un actionPerformed.
    Vous aller me dire c'est simple, suffit d'afficher la deuxième fenêtre quand l'utilisateur a cliquer sur "ok" de la première fenêtre, mais en fait le code que j'ai là ne me permet pas de le faire. (C'est exceptionnel)
    • Partager sur Facebook
    • Partager sur Twitter
      31 mars 2009 à 20:01:58

      Citation : Pas de titre

      Vous aller me dire c'est simple, suffit d'afficher la deuxième fenêtre quand l'utilisateur a cliquer sur "ok" de la première fenêtre, mais en fait le code que j'ai là ne me permet pas de le faire. (C'est exceptionnel)


      Et pourquoi cela ?

      Quoiqu'il arrive tu peux récupérer une valeur de retour de ta JDialog, à partir de là, tu peux exécuter d'autres actions.

      Swing a un thread propre à lui créé par la JVM pour afficher ses composants et écouter tes fenêtres. Il ne faut pas toucher à ce thread directement. Il y'a la classe javax.swing.SwingUtilities pour tout ce qui concerne ce thread, mais bon ça m'étonnerait fort que tu en aies besoin pour faire ce que tu veux.

      En répondant à ma première question j'aurai sûrement une solution pour toi.
      • Partager sur Facebook
      • Partager sur Twitter
        31 mars 2009 à 20:17:57

        Euh, ma première JDialog en fait ne renvoie pas de valeur, ce sont des boutons d'option.

        En fait j'ai un menu et quand je clique sur ajouter un média, il m'affiche la première JDialog me demandant quel type de média il faut ajouter, mais en attendant je fais des contrôles (à l'aide du Pattern MVC) car seul l'administrateur peut ajouter des médias.
        Du coup bah quand je clique sur le menu, il vérifie si c'est bien l'admin qui est connecté, si oui, je demande à la vue d'afficher la première JDialog demandant le type de média à ajouter. (J'ai créer une classe à part qui gère toutes les JDialog dans la vue)

        Et comme tu vois cette classe d'appelle OptionDialog et possède des méthodes statiques pour créer mes JDialog.

        Le problème est donc là : ma méthode actionPerfomed se trouve dans la classe OptionDialog et mes OptionDialog s'affiche dans une autre classe. (La vue)
        Et ma vue n'a aucun moyen de savoir quand est ce que l'utilisateur a cliqué sur ok, du coup il faudrait que je puisse arrêter l'exécution des instructions là ou j'ai mis mon wait() (après l'affichage de la première JDialog) et ne pas la reprendre tant que l'utilisateur n'a pas cliquer sur le bouton ok, et enfin afficher la seconde JDialog.
        Sleep ne serait pas utile car ça endors un certains temps.

        Sinon j'avais penser faire aussi une boucle et dire tant que le composant est affiché à l'écran, on ne continue pas, mais ça plante, là c'est l'intérieur de la JDialog qui ne s'affiche plus et je ne sais plus fermer le programme donc là c'est blocage total.

        Voilà j'espère que j'ai répondu à tes questions.



        • Partager sur Facebook
        • Partager sur Twitter
          31 mars 2009 à 20:40:24

          Et tu utilises quoi comme JDialog qui n'a pas de valeur de retour ? Tu instancies des JDialog toi-même ? Ne pourrais-tu pas choisir une des classes présentes ici : http://java.sun.com/docs/books/tutoria [...] s/dialog.html

          Sinon tu n'as qu'à passer l'info du clic de bouton en utilisant le pattern observer, c'est un des principes de MVC normalement ?
          Dès qu'un clic sur bouton, dis à ma vue qu'elle peut lancer la seconde JDialog.

          Au pire tu peux récupérer tous les listeners associés à ta JDialog, donc y'a pas mal de possibilités pour toi.
          • Partager sur Facebook
          • Partager sur Twitter
            31 mars 2009 à 20:48:13

            Bah finalement j'ai fait autrement, j'ai crée uen méthode privée dans OptionDialog qui affiche la deuxième JDialog mais je trouves que c'est bof comme solution.

            Le pattern MVC c'est bien mais quand il y a des contrôles à faire, sinon, si y'a pas de contrôle à faire, je passe directement à l'étape suivante sans envoyer les info au contrôleur ni au model, mais bon, pourquoi pas avoir une méthode dans mon contrôleur qui vérifie si l'utilisateur à entrer les info dans la première JDialog, et si oui, demander à la vue d'afficher la seconde JDialog, mais je ne vois pas trop comment implémenter ça.

            Y'a moyen de récupérer le listener de ma première fenêtre dans le contrôler et de vérifier si le bouton ok à été cliqué ?

            Elle me plait bien cette solution mais je ne vois pas du tout comment l'implémenter, fin récupérer le listener ça va après ...
            • Partager sur Facebook
            • Partager sur Twitter
              31 mars 2009 à 21:34:13

              Si je reprends une phrase de shakhal qui m'a bien plu y'a pas longtemps : "il faut utiliser les design pattern pour répondre à un besoin et non pas pour utiliser un pattern".

              Sinon ton contrôleur sert justement à ça. D'après ce que j'ai compris, tu instancies des JDialog brutes, mais tu dois bien y ajouter un JButton ok non ?
              Tu fais écouter ton JButton par ton contrôleur, dès que le JButton a été cliqué tu envoies l'info au modèle ou à la vue (selon tes besoins) de créer une seconde JDialog. Je ne vois pas où tu bloques, ou je rate un détail, mais comme je me suis déjà posé cette question...

              Euh je ne sais plus où je voulais en venir en disant tu peux récupérer les Listeners, enfin ils ont sûrement des méthodes mais peut-être pas intéressantes pour ton cas. Par contre tu peux ajouter des Listeners à ta JDialog. C'est relativement propre en contrôlant bien qui écoute.
              • Partager sur Facebook
              • Partager sur Twitter
                31 mars 2009 à 21:46:13

                Bah wai, je vasi faire comme ça, dès que je clique sur ok je vasi directement envoyer l'info au modèle qui affichera le seconde JDialog puique bon y'a pas de contrôles à faire.

                Euh enfin j'vé essayer mais je pense pas qu'il y ai moyen de récupérer le modèle dans la vue, par contre dans le contrôleur nickel, au pire, j'invoque une méthode du contrôleur et là j'invoque une méthode dans le modèle qui elle demandera à la vue d'afficher la seconde JDialog.

                Par contre bah comme c'est des boutons d'option, l'utilisateur peut mal de se tromper, donc, j'ai fais une variable dans OptionDialog et je récupère la bonne valeur.
                Enfin soit, je crois finalement que je vais rester sur mon idées, j'appelle la seconde JDialog dans OptionDialog et après seulement j'envoie au contrôleur, au lieu de faire afficher les deux JDialog l'une après l'autre dans la vue.

                Enfin mon projet comporte 20 classes, je vais pas toutes les mettres. :D

                Et c'est pas finis, à la fin je pense qu'il contiendra 30 classes, si pas plus.
                Sinon le reste ça fonctionne nickel, il me sauve bien tout dans les fichiers grâce à la séréalisations, les connections et inscription des membres et contrôles des droits d'accès et tout, ça fonctionne super grâce au pattern MVC.
                Y'a juste ce petit truc là que je me demande si y'a pas moyen de "coucircuiter" le pattern MVC parce que bon, j'imagine j'ai plus de trois JDialog à afficher l'une après l'autre avec des boutons d'options, je dois à chaque fois envoyer les infos au contrôleur et au modèle puis enfin à la vue.

                Hors que je pourrai dire à la vue : "Voilà, maintenant tu va m'afficher cette JDialog là, attendre que l'utilisateur ai cliqué sur ok puis m'afficher la suivante.

                Ce que j'aimerai faire en fait c'est envoyer directement l'info à la vue lorsque l'utilisateur à cliqué sur ok, mais je ne vois pas trop comment faire.
                Peut être en appelant une méthode dans la vue dans mon actionPerformed qui affiche la seconde JDialog parce que le main continue à s'exécuter pendant l'affichage d'une fenêtre et c'est logique.

                Et si je fais une boucle dans le main avec une variable qui vaut false tant que l'utilisateur n'a pas cliquer sur "ok" ça ne fonctionne pas non plus.

                Je vais tenter de le faire via une méthode à part dans la vue, c'est le mieux je penses.

                Ha oui voilà, quand je fais avec une variable booléenne, la boucle de ma vue attends bien que l'on ai cliqué sur "ok" mais le problème est dans le fait que ma JDialog ne s'affiche pas bien et le programme bloque, du coup je ne sais même plus cliquer sur ok pour continuer.

                Et aussi, imagine celui qui veut afficher un message pensant x secondes, en fait j'ai aussi le même problème avec un jeux, je veux afficher un message pendant x secondes, le contour de la fenêtre s'affiche mais pas ce qu'il y a à l'intérieur, puis x secondes plus tard la fenêtre part bien et c'est ça que je trouve bizarre.

                Ou alors c'est le Thread de swing qui attends que la méthode dans le main aie finis de s'exécuter avant d'afficher le contenu dans la fenêtre, ça c'est un peu agaçant.






                • Partager sur Facebook
                • Partager sur Twitter
                  31 mars 2009 à 22:42:53

                  Je t'ai bien dit que l'EDT (le thread utilisé par Swing) ne devait pas être manipulé. Et il n'a pas à l'être. C'est lui gère le bon fonctionnement de tes fenêtres. Si tu fais une boucle infinie dans ce thread, tu ne sors pu de la boucle, et donc ton programme ne répondra plus puisque les méthodes de la boucle n'auront pas été dépilées de l'EDT !

                  Si tu tiens tant que ça à faire ta boucle, et que tu dis que c'est juste ton programme qui se bloque, dans ce cas mets ta boucle dans un nouveau thread. Perso je trouve ça plus moche comme méthode que de tout faire passer par des Observer-Observable.

                  [EDIT]

                  Citation : Pas de titre

                  Ce que j'aimerai faire en fait c'est envoyer directement l'info à la vue lorsque l'utilisateur à cliqué sur ok, mais je ne vois pas trop comment faire.


                  tonJButton.addActionListener(new ActionListener()
                     {
                        public void actionPerformed(ActionEvent e) {
                           notifyObserver();
                        }
                     }
                  );
                  

                  où l'observeur en question est ta vue.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 mars 2009 à 22:48:07

                    Attend je te me un code simple pour que tu comprennes mieux.



                    package interGraph;
                    import javax.swing.*;
                    
                    import java.awt.BorderLayout;
                    import java.awt.event.*;
                    import javax.swing.event.*;
                    
                    public class Fenetre extends JFrame   {
                    	private SousFenetre sf;
                    	
                    	public Fenetre () {
                    		super ("La fenêtre.");
                    		setDefaultCloseOperation(EXIT_ON_CLOSE);
                    		
                    		add(new JLabel ("La fenêtre."));
                    		sf = new SousFenetre (this, "Sour fenêtre.");
                    		
                    		pack ();
                    	}
                    	public void afficher () {
                    		setVisible (true);
                    		sf.afficher ();
                    	}
                    	public SousFenetre getSF () {
                    		return sf;
                    	}
                    	public static void main (String[] args) {
                    		Fenetre fen = new Fenetre ();
                    		
                    		fen.afficher ();
                    		
                    		while (!fen.getSF().getCont()) {
                    			System.out.println(fen.getSF().getCont());
                    		}
                    		fen.getSF().setVisible(false);
                    		fen.lancementSecSousFenetre();
                    	}
                    	public void lancementSecSousFenetre () {
                    		System.out.println("Lancement de la seconde sous fenêtre.");
                    	}
                    	private class SousFenetre extends JDialog implements ActionListener {
                    		private boolean cont;
                    		public SousFenetre (JFrame parent, String titre) {
                    			super (parent, titre);
                    			
                    			add(new JLabel ("La sous fenêtre qui s'affiche pendant deux secondes"), BorderLayout.NORTH);
                    			JButton ok = new JButton ("Ok");
                    			add(new JButton ("OK"), BorderLayout.SOUTH);
                    			ok.addActionListener (this);
                    			pack ();
                    			
                    			cont = false;
                    		}
                    		
                    		public void afficher () {
                    			setVisible (true);
                    		}
                    		public void actionPerformed (ActionEvent e) {
                    			
                    				cont = true;
                    			
                    		}
                    		public boolean getCont () {
                    			
                    			return cont;			
                    		}		
                    	}	
                    }
                    

                    Voilà, là il ne met pas le cont à true et donc la lancera pas la seconde fenêtre.

                    Masi là le prog ne bloque pas et la JDialog s'affiche bien. o_O
                    Bizarre c'est à n'y rien comprendre.

                    PS : Sinon si je veux faire appel à notifyObserver, je dois faire comme ça parce que notifyObserver c'est le modèle qui appelle cette méthode normalement :
                    (dans mon actionPerformed)

                    MediastoreModel model = (MediastoreModel) controler.getModel();
                    model.notifyObserver ("ShowAddMediaBox");
                    


                    J'pense que je vais en rester là, tant pire, façon quoi que je fasse je devrai toujours passer par le modèle et le controleur pour mettre à jour la vue, y'a sans doute pas moyen de faire autrement, à moins si je tente le coup d'un héritage de la classe Abstraite Model et que je redéfinis notifyObserver mais là ça va être spécial car j'aurais en fait, deux modèles.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      1 avril 2009 à 0:05:18

                      Y'a comme un petit soucis là :
                      JButton ok = new JButton ("Ok");
                      			add(new JButton ("OK"), BorderLayout.SOUTH);
                      			ok.addActionListener (this);
                      

                      Tu ajoutes un nouveau bouton, c'est le bouton "ok" qu'il faut ajouter.


                      Citation : Pas de titre

                      PS : Sinon si je veux faire appel à notifyObserver, je dois faire comme ça parce que notifyObserver c'est le modèle qui appelle cette méthode normalement :
                      (dans mon actionPerformed)


                      Tu peux aussi simplement créer deux interfaces Observer et Observable avec dans Observable un nom de méthode différent de notifyObserver.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        1 avril 2009 à 15:26:43

                        Euh oui en fait j'ai déjà les interfaces Observable et observer, je sais que je pourrai très bien m'en resservir, façon pas le choix sinon j'ai un prob de méthode qui reste au dessus de la pile.

                        Wai finalement je crois que je vais implémenter Observable également dans OptionDialog un truc du genre enfin bon en relisant le tutos de cysboy sur le pattern Oberver ça devrais aller, là ce qui me perturbe je pense c'est que je doit implémenter deux fois le même pattern dans la même application, je pense que je vais ajouter un Observer sur ma première JDialog et lorsqu'on clique sur le bouton ok j'appelle notifyObserver qui fera appelle à update de la vue qui affichera la seconde JDialog. (Fiouf, compliqué tout ça)

                        Perso je commence à savoir implémenter des trucs compliqués, pas mécontent de ma formation. (Même si y'a pas mal de cours ennuyant comme le COBOL)

                        PS : Ok nickel ça marche, suffisait d'impélmenter Observable dans OptionDialog et d'rajouter la fenêtre principale en tant qu'observer et d'appeler notifyObserver dans mon actionPerformed!

                        Ce qui à eu c'est que j'étais perdu parce que voilà en utilisant les pattern composé ça m'a fait tout drôle de revenir à un pattern plus simple. o_O

                        Pour le code d'au dessus en effet y'a un blème j'ai oublier de modifier pour le JButton.

                        J'ai compris en fait celui là marche parce il n'y a pas de design pattern du coup la pile de méthode ne reste pas bloquée comme c'est le cas de ma méthode update dans ma vue.
                        Enfin soit j'ai toujours eu du mal à comprendre en fait même à la fin de l'animation, pourquoi est ce que quand il reclique sur "ok" ça bloque.

                        Ha bah si, c'est parce que il démarre l'animation dans la méthode actionPerformed dans le même Thread du coup, la méthode actionPerformed a pas finis son exécution et ne peux donc pas être ré appelée car elle n'a pas été dépilée.

                        C'est un truc du même genre qui se passe dans mon cas. (Mais en plus compliqué)
                        Purée j'ai enfin compris. :lol:
                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 avril 2009 à 17:18:12

                          C'est tout à fait cela, mais y'a même un problème dans le tuto de cysboy mais bon.
                          J'ai essayé de compiler son code refait tout à la fin et la fenêtre ne répond pas.
                          Enfin bon je n'aime pas beaucoup son tuto sur la partie évènementielle, je préfère ceux de Sun qui indiquent tout de suite les bonnes méthodes.

                          A propos des interfaces Observer et Observable, j'espère que tu ne respectes pas le tuto à la lettre. Tu appelles tes interfaces comme tu veux, elles servent à former un super type pour la liste d'observateurs. Par ailleurs moi dans mes interfaces de type Observable, je ne mets que les méthodes addObserver et notify ça suffit largement. Comme j'avais besoin de passer un objet à une autre classe, j'avais besoin d'une méthode notify différente à chaque fois, donc j'ai créé beaucoup d'interfaces de type Observable. Maintenant c'est vrai que j'ignore s'il y'a un meilleur moyen.


                          P.S. C'est marrant d'être modérateur :) Même si à mon avis c'est un bon poisson d'Avril XD
                          • Partager sur Facebook
                          • Partager sur Twitter
                            1 avril 2009 à 17:27:24

                            Citation : elmh

                            P.S. C'est marrant d'être modérateur :) Même si à mon avis c'est un bon poisson d'Avril XD


                            Ou un bug de la nouvelle interface :p Mais on a pas le droit de modérer en tout cas ^^
                            • Partager sur Facebook
                            • Partager sur Twitter
                              1 avril 2009 à 18:05:05

                              Bah non moi j'ai utiliser la même interface Obervable pour mes deux classes.

                              (Un même objet peut avoir plusieurs observateurs)

                              Du coup ma vue n'a plus qu'un seul Observateur, mais deux.
                              Donc j'ai deux classe qui impélmentent Observable et dans lesquelles je redéfinis notifyAll.
                              Et daans notifyObserver j'envoie un paramètre pour dire quels mise à jour il faut faire.
                              Ainsi voilà lorsque j'apelle update de tout les Observer je leur envoie le type de mise à jour et j'vais un test dans la méthode update avec equals sur le type d'action à faire, un peut comme ActionEvent mais avec des String.

                              En fait j'ai implémenter Observable dans ma classe AbstractModel mais aussi dans OptionDialog, et ma vue implémente Observer, du coup voilà je peux appeler notifyObserver à partir du model mais aussi à partir de OptionDialog qui remettent mes vues à jour. :D

                              Et non je ne suis pas à 100% le tuto de cysboy, je ne l'aime pas de trop. (Surtout pour la partie évènementielle, mais aussi pour le contenu trop pauvre de certains chapitre)

                              PS : oui et les modérateur on un autre truc : boulay. :lol:




                              • Partager sur Facebook
                              • Partager sur Twitter

                              Petite problème.

                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                              • Editeur
                              • Markdown