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

EDT/SwingWorker Java Discussion :

doClick() ne respecte pas son temps


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 84
    Points : 67
    Points
    67
    Par défaut doClick() ne respecte pas son temps
    Voilà, j'ai un tableau de bouton(4), pour un jeu Simon Says.

    La logique est impécable, mais au niveau de l'animation j'ai un problème.

    Problème: Lorsque j'apelle doClick(400) sur le bouton vert et tout de suite après le bouton rouge, le bouton vert n'enlève pas sont état pesez jusq'attend que les autres boutons(ici rouge) termine leur doClick(400).

    Pourtant, les doClick des différents boutons ne s'éxécute pas en même temps, ce qui me tracace puisqu'il termine en même temps.

    Voici le code en particulier:
    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
        public void run(JButton tableauDeBoutons[], LinkedList<Integer> LL) {
        	LL.add(GUI.genererEntre3et0());
     
        	for (int i = 0; i < LL.size(); i++) {
        		try {
        			Thread.sleep(400);
        		} 
     
        		catch (InterruptedException e) {
        			// TODO Auto-generated catch block
        			e.printStackTrace();
        		}
    			tableauDeBoutons[LL.get(i)].doClick(400);	
    		}
     
     
     
     
     
        }
    Le tableau de bouton:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    tableauDeBoutons[0] = vert;
    		tableauDeBoutons[1] = rouge;
    		tableauDeBoutons[2] = jaune;
    		tableauDeBoutons[3] = bleu;
    		for (int i = 0; i < tableauDeBoutons.length; i++) {
    			tableauDeBoutons[i].setBorder(CONTOUR);
    			tableauDeBoutons[i].addMouseListener(new clicJoueur(i));
    		}
    		vert.setName("0");
    		rouge.setName("1");
    		vert.setPressedIcon(new ImageIcon("images/vert2.png"));
    		rouge.setPressedIcon(new ImageIcon("images/rouge2.png"));
    		jaune.setPressedIcon(new ImageIcon("images/jaune2.png"));
    		bleu.setPressedIcon(new ImageIcon("images/bleu2.png"));

  2. #2
    Membre expérimenté
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 050
    Points : 1 340
    Points
    1 340
    Par défaut
    Bonjour,

    Ça sent le problème d'EDT.

    Voici un code qui simule ce que tu obtiens. L'animation est faite entièrement dans l'EDT, ce qui bloque les boutons jusqu'à la fin.

    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
    import java.awt.FlowLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
     
    public class Test2 extends JFrame {
     
    	public static void main(String[] args) {
    		Test2 t = new Test2();
    		t.pack();
    		t.setVisible(true);
     
    		SwingUtilities.invokeLater(new Runnable() {			
    			@Override
    			public void run() {
    				for (final JButton btn : boutons) {
    		    			try {
    		    				Thread.sleep(500);
    		    			} catch (InterruptedException e) {
    		    				//
    		    			}
    		    			btn.doClick(1000);
    				}
    			}
    		});
    	}
     
    	private static JButton[] boutons;
     
    	public Test2() {
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		getContentPane().setLayout(new FlowLayout());
    		this.boutons = new JButton[5];
    		for (int i = 0; i < 5; i++) {
    			this.boutons[i] = new JButton("" + i);
    			getContentPane().add(this.boutons[i]);
    		}
     
    	}
     
    }
    La solution consiste à seulement exécuter le doClick dans l'EDT.

    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
    import java.awt.FlowLayout;
    import java.lang.reflect.InvocationTargetException;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.SwingUtilities;
     
    public class Test extends JFrame {
     
    	public static void main(String[] args) {
    		Test t = new Test();
    		t.pack();
    		t.setVisible(true);
    	}
     
    	private JButton[] boutons;
     
    	public Test() {
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		getContentPane().setLayout(new FlowLayout());
    		this.boutons = new JButton[5];
    		for (int i = 0; i < 5; i++) {
    			this.boutons[i] = new JButton("" + i);
    			getContentPane().add(this.boutons[i]);
    		}
    		Anim anim = new Anim();
    		anim.start();
    	}
     
    	private class Anim extends Thread {
    		@Override
    		public void run() {
    			for (final JButton btn : Test.this.boutons) {
    	    			try {
    	    				Thread.sleep(500);
    	    			} catch (InterruptedException e) {
    	    				//
    	    			}
    	    			try {
    					SwingUtilities.invokeAndWait(new Runnable() {					
    						@Override
    						public void run() {
    							btn.doClick(1000);
    						}
    					});
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				} catch (InvocationTargetException e) {
    					e.printStackTrace();
    				}
    			}
    	    	}
    	}
     
    }

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    84
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 84
    Points : 67
    Points
    67
    Par défaut
    Citation Envoyé par visiwi Voir le message
    Bonjour,

    Ça sent le problème d'EDT.
    Merci beaucoup, j'ai pu utiliser ton exemple pour l'adapter a mon problème et tout marche à merveille.

    J'aurais quelques questions,

    Si je remplace start() par run()
    Anim anim = new Anim(memoireOrdi, tableauDeBoutons);
    anim.run();

    L'effet obtenu est comme dans ton première exemple, tandis qu'avec l'appelation de .start() les doClick() fonctionnes. Pourquoi?

    Secondo, j'ai remarqué que tu n'a même pas eu besoin de passer ton tableau de bouton de la classe externe à la classe interne, j'aimerai savoir comment au juste.

    J'ai été forcé de modifier le constructeur pour passé mon LinkedList et mon tableau de bouton(Puisque j'avais besoin de crée une séquence).
    Voici mon code finalement:
    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
    private class Anim extends Thread {
     
    		LinkedList<Integer> LLi = new LinkedList<Integer>();
    		JButton tab[] = new JButton[4];
     
    		public Anim(LinkedList<Integer> LL,JButton tab[]){
    			for (int i = 0; i < LL.size(); i++) {
    				LLi.add(LL.get(i));
    			}
    			for (int i = 0; i < tab.length; i++) {
    				this.tab[i] = tab[i];
    			}
    		}
    		public void run() {
    			for (int i = 0; i < LLi.size(); i++) {
    				try {
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				tab[LLi.get(i)].doClick(400);
    			}
    	    	}
    	}

  4. #4
    Membre expérimenté
    Avatar de visiwi
    Profil pro
    Inscrit en
    Février 2008
    Messages
    1 050
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 1 050
    Points : 1 340
    Points
    1 340
    Par défaut
    Citation Envoyé par Yakuzan Voir le message
    L'effet obtenu est comme dans ton première exemple, tandis qu'avec l'appelation de .start() les doClick() fonctionnes. Pourquoi?
    Si tu appel la méthode run(), le code est exécuté, mais pas dans le Thread. Pour le lancer dans un Thread il faut appeler la méthode start(). Or comme ton problème venait du fait que tout était lancé dans l'EDT, le fait de lancer le code dans un thread te permet de "sortir" de l'EDT.

    Citation Envoyé par Yakuzan Voir le message
    Secondo, j'ai remarqué que tu n'a même pas eu besoin de passer ton tableau de bouton de la classe externe à la classe interne, j'aimerai savoir comment au juste.
    C'est un des avantages des classes interne, tu as accès à tous les attributs de la classe. Dans "penser en Java" (disponible sur developpez.com), tu as tout un chapitre sur le sujet.

    Ne serait-il pas plus simple de passer une liste ordonnée de JButton plutôt que d'Integer + le tableau de boutons ?

    Les copies d'objets de ta liste et tableau ne sont telles pas inutile ?

    Enfin je te conseil de respecter les conventions de nommage, et de nommer tes attributs et variable de façon plus explicite, tu verras qu'à terme ton code est bien plus lisible. Définir une visibilité la plus restreinte possible est aussi une bonne habitude, si je puis me permettre : ton code n'en sera que plus fiable.

    Par exemple, et à titre indicatif :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    private LinkedList<Integer> listIndiceBouton = new LinkedList<Integer>();
    private JButton boutons[] = new JButton[4];

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

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