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 :

Problème avec l'instruction Thread.sleep


Sujet :

EDT/SwingWorker Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut Problème avec l'instruction Thread.sleep
    [I]Bonjour,
    Dans le cadre d'un petit programme, j'a réalisé une application qui est censée afficher alternativement une image puis une autre image. Pour cela j'ai utilisé l'instruction Thread.sleep() pour que le programme affiche une image, attende 1 seconde, affiche une autre image, attende 1 seconde...

    Lorsque j'exécute ce programme à part, tout se passe bien, mais lorsque j'intègre le code du programme dans un autre programme (qui est en fait le menu du logiciel), le Thread.sleep ne marche pas, et au lieu d'afficher alternativement les deux images, la fenêtre reste blanche au début puis affiche seulement la dernière image.

    Voici le code source du programme qui fonctionne correctement quand il est lancé à part :

    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
     
    public class Fenetre extends JFrame {
    	public Fenetre() {         
    		new JFrame();
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		this.setContentPane(new Panneau2());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate();
    		this.setContentPane(new Panneau());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate(); 
    		this.setContentPane(new Panneau2());
     
    	}
    }
    Les classes Panneau et Panneau2 servent seulement à afficher l'une ou l'autre des deux images.

    Et voici comment j'intègre le code précédent au code du menu (je ne mets que la partie du code qui correspond car le code entier est trop long) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     
    public static class Test extends JPanel  implements ActionListener{
     
    		public void actionPerformed (ActionEvent e){ 
     
    			fenetre.dispose();
    				new Fenetre();
    		}
     
     
     
    	}
    Je ne sais pas à quel niveau se situe le problème, mais il est possible qu'il y ait des erreurs liées au fait que je débute en java, donc merci de me signaler si quelque chose ne va pas.
    Je vous remercie de votre aide.

  2. #2
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Tu à essayé de l'intégrer dans un thread à part? Parce que là le thread de ton jpanel aussi prend le sleep...

    Et au passage, ta fenêtre étend jframe, donc ne fais pas new jframe() dans ton constructeur mais super()
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    avec des Thread.sleep, tu bloque le thread courant. Avec ton intégration, le thread courant, c'est le thread graphique => tu bloque l'interface graphique.

    Tu ne devrais pas faire de Thread.sleep, en encore moins dans un constructeur. On attends d'un constructeur qu'il construise et préparer l'objet, pas qu'il fasse tout y compris le café.

    Dans ton cas, si cette fenêtre a pour but de faire défiler des images, je te recommanderais:

    d'utiliser javax.swing.Timer pour gérer le défilement
    de démarrer ce timer soit dans le constructeur (démarrage automatique), soit dans une méthode à part, que tu appellerais après avoir construit la fenêtre (à préférer, ça évite d'exposer this avant la fin du constructeur)

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    cafeinoman : merci pour l'indication concernant le JFrame.
    tchize : comment est-ce que je peux utiliser le timer dans ce cas, parce que je dois faire afficher deux images alternativement, mais pour l'instant j'ai seulement trouvé la méthode scheduleAtFixedRate() qui permet d'exécuter une action de manière périodique, donc si tu connais une instruction qui puisse m'être utile, je suis preneur.
    Merci.

  5. #5
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    ben oui, a intervale régulier, tu change l'image, tout simplement

  6. #6
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Si j'ai bien compris la suggestion de Tchize :

    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
     
    public class Fenetre extends JFrame {
    	public Fenetre() {         
    		super();
                    init();
     
    		this.setContentPane(new Panneau2());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate();
    		this.setContentPane(new Panneau());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate(); 
    		this.setContentPane(new Panneau2());
     
    	}
     
            private void init () {
                    this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(
                           JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
                    int pan=0;
                    ActionListener listener = new ActionListener (
     
                         @Override
                         public void actionPerformed(ActionEvent evt) {
                         switch(pan++% 2){
                         case (0):this.setContentPane ( new Panneau ( ) ); break;
                         case (1):this.setContentPane ( new Panneau2 ( ) ); break;
                         }      
                 }
                 Timer timer = new Timer (1000, listener);
                 timer.start ();
           }
     
    }
    Bon courage.
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    salut,
    en réponse à cafeinoman, j'ai un problème avec la méthode private void init() : il me semble que tu t'es trompé après le new ActionListener : tu rajoutes une parenthèse, mais du coup lorsque je l'enlève, j'ai beau tout essayer (doubles parenthèses, accolades...), eclipse me signale des erreurs sur les accolades... je ne vois pas où est le problème :
    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
     
     
    public class Fenetre extends JFrame {
    	public Fenetre() {         
    		super();
    		init();
     
    		this.setContentPane(new Panneau2());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate();
    		this.setContentPane(new Panneau());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate(); 
    		this.setContentPane(new Panneau2());
     
    	}
     
    	private void init () {
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(
    				JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		int pan=0;
    		ActionListener listener = new ActionListener (
     
    				@Override
    				public void actionPerformed(ActionEvent evt) {
    					switch(pan++% 2){
    					case (0):this.setContentPane ( new Panneau ( ) ); break;
    					case (1):this.setContentPane ( new Panneau2 ( ) ); break;
    					}      
    				}
    				Timer timer = new Timer (1000, listener);
    				timer.start ();
    	}
     
    }
    sinon cela me semble une bonne idée mais est-ce que le problème sera résolu malgré qu'il y ait encore le Thread.sleep() ? Parce que d'après mes essais c'est bien cette instruction qui posait problème lorsque le programme lagguait.

  8. #8
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Oui, désolé, je poste depuis mon téléphone... il faut après avoir fermé l'accolade du ActionListener fermer la parenthèse et mettre le ; , comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    timer.start ();
    	});
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

  9. #9
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    Je corrige parce qu'il faudrait pas poster du code depuis un téléphone, c'est moche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    		ActionListener listener = new ActionListener (){ // <- accolade de début de classe anonyme
     
    				@Override
    				public void actionPerformed(ActionEvent evt) {
    					switch(pan++% 2){
    					case (0):this.setContentPane ( new Panneau ( ) ); break;
    					case (1):this.setContentPane ( new Panneau2 ( ) ); break;
    					}      
    				} // fin de méthode
    }; // fin de classe et fin dinstruction
    				Timer timer = new Timer (1000, listener);
    				timer.start ();

  10. #10
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Effectivement
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Sauf que du coup il me met une erreur sur le .start() : "method .start() is undefined for the type Timer", et il me met aussi une erreur sur le new Timer(1000,listener) : "The constructor Timer(int, ActionListener) is undefined" .
    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
     
    private void init () {
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		final int pan=0;
    		ActionListener listener = new ActionListener (){ // <- accolade de début de classe anonyme
     
    			@Override
    			public void actionPerformed(ActionEvent evt) {
    				switch(pan++% 2){
    				case (0):this.setContentPane ( new Panneau ( ) ); break;
    				case (1):this.setContentPane ( new Panneau2 ( ) ); break;
    				}      
    			} // fin de méthode
    		}; // fin de classe et fin dinstruction
    		Timer timer = new Timer (1000, listener);
    		timer.start ();
    	}
    une idée ?

  12. #12
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Oui : vérifie tes imports, c'est javax.swing.Timer, pas java.util.Timer. Ou alors la javadoc est fausse
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Effectivement il s'agissait de cela.
    Mais il me reste encore un problème (je commence à en avoir assez ) : il me dit que la méthode setContentPane () est undefined pour le type new ActionListener. Je ne sais pas si c'est encore un problème d'import, mais j'ai tout essayé et ça ne veut toujours pas m'enlever cette erreur.
    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
     
     
    private void init () {
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		ActionListener listener = new ActionListener (){ // <- accolade de début de classe anonyme
     
    			@Override
    			public void actionPerformed(ActionEvent evt) {
    				int pan =0;
    				switch(pan++% 2){
    				case (0):this.setContentPane(new Panneau()); break;
    				case (1):this.setContentPane(new Panneau2 ()); break;
    				}      
    			} // fin de méthode
    		}; // fin de classe et fin dinstruction
    		Timer timer = new Timer (1000, listener);
    		timer.start ();
    	}

  14. #14
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    retire ce this.


    il référence la classe en cours, mais n'est nécessaire qu'en cas d'ambiguité. Et là, non seulement tu n'a pas d'ambiguité (Fenetre et la seule classe courante à avoir une méthode setContentPane), mais this représente à ce niveau là ActionListener et non pas Fenetre, donc c'est une erreur.

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    J'ai bien retiré this, mais du coup, qu'est-ce que je dois mettre à la place ? J'ai essayé de créer le JFrame dans la méthode init(), mais lorsque je lance le programme, ça m'affiche seulement une image, celle de Panneau2().
    Voici le code :

    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
     
    public class Fenetre extends JFrame {
    	public Fenetre() {         
    		init();
     
    		this.setContentPane(new Panneau2());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate();
    		this.setContentPane(new Panneau());
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		this.validate(); 
    		this.setContentPane(new Panneau2());
     
    	}
     
    	private void init () {
    		final JFrame fen = new JFrame();
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		ActionListener listener = new ActionListener (){ // <- accolade de début de classe anonyme
     
    			@Override
    			public void actionPerformed(ActionEvent evt) {
    				int pan = 0;
    				switch(pan++% 2){
    				case (0):fen.setContentPane(new Panneau()); break;
    				case (1):fen.setContentPane(new Panneau2 ()); break;
    				}      
    			} // fin de méthode
    		}; // fin de classe et fin dinstruction
    		Timer timer = new Timer (1000, listener);
    		timer.start ();
    	}
    }
    J'ajoute aussi que la méthode init() ne semble pas fonctionner : lorsque j'enlève cette méthode, le résultat est le même. Je commence à surchauffer

  16. #16
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Quand @Tchize_ t'a dit de retirer le this (sous entendu celui dans l'action listener, pour lequel tu invoques setContentPane), il ne t'a pas dit de le remplacer par la référence d'une autre fenêtre. L'enlever, c'est juste l'enlever. Cette méthode (setContentPane) est une méthode de JFrame, pas de ActionListener, donc l'invoquer sur this était indiqué comme une erreur (méthode inexistante sur ActionListener) : le fait d'enlever "this." permettait de l'invoquer sur l'instance de classe englobante, soit la fenêtre Fenetre. Là, ce que tu as fait, c'est créer une nouvelle instance de JFrame, référencée par la variable fen, mais qui n'est jamais affichée.
    Si tu veux explicitement indiquer le this, tu peux écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    @Override
    public void actionPerformed(ActionEvent evt) {
       int pan = 0;
       switch(pan++% 2){
          case 0:Fenetre.this.setContentPane(new Panneau()); break;
          case 1:Fenetre.this.setContentPane(new Panneau2 ()); break;
       }      
    } // fin de méthode

    Ensuite, la variable pan est créée à chaque invocation de actionPerformed, elle risque pas de changer de valeur, donc ça affichera toujours la même image.

    Il faudrait créer une variable d'instance :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
       private int pan = 0;
    @Override
    public void actionPerformed(ActionEvent evt) {
       switch(pan++% 2){
          case 0:Fenetre.this.setContentPane(new Panneau()); break;
          case 1:Fenetre.this.setContentPane(new Panneau2 ()); break;
       }      
     
    } // fin de méthode
    Si tu n'as que 2 images, tu peux utiliser aussi juste un booléen et faire un not à chaque appel (ou pan=1-pan).

    D'autres part, enlèves également tout le code dans le constructeur de la fenêtre qui se trouve après l'appel de init : c'est le timer qui est chargé de faire le changement et en plus les sleep() bloque l'ui pendant la constructeur de la fenêtre, comme déjà dit par @Tchize_ (et donc tu ne verras que l'état final de l'éxécution de ce code, pas les étapes intermédiaires, en plus de bloquer l'UI.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    Bonjour,
    J'ai suivi vos indications et le programme marche cette fois-ci. Je tenais donc à vous remercier pour vos différentes aides et conseils. Cependant, il me reste deux petites questions : lorsque la fenêtre s'ouvre, il y a un très court temps de "latence" pendant lequel l'écran est gris : savez-vous d'où cela peut-il venir ? Et deuxième question : si j'ai besoin d'afficher successivement 5 images, comment dois-je modifier la boucle, et surtout y a-t-il un moyen plus rapide que de créer 5 classes différentes "Panneau1.java", "Panneau2.java", etc... pour afficher une image ?

    Pour indication, je mets le code de la classe fenêtre désormais fonctionnelle :
    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
     
    public class Fenetre extends JFrame {
     
    	public Fenetre() {         
    		super();
    		init(); 
    	}
     
    	private void init () {
    		this.setTitle("Série d'images");
    		this.setSize(500, 500);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
     
    		ActionListener listener = new ActionListener (){ // <- accolade de début de classe anonyme
    			private int pan = 0;
    			@Override
    			public void actionPerformed(ActionEvent evt) {
    				switch(pan++% 2){
    				case (0):Fenetre.this.setContentPane(new Panneau()); Fenetre.this.validate(); break;
    				case (1):Fenetre.this.setContentPane(new Panneau2 ()); Fenetre.this.validate(); break;
    				}      
    			}
    		};
    		Timer timer = new Timer (1000, listener);
    		timer.start ();
    	}
    }
    Et le code de la classe "Panneau" qui sert à afficher l'une des images :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public class Panneau extends JPanel { 
    	public void paintComponent(Graphics g){
    		try {
    			BufferedImage img = ImageIO.read(new File("images.jpg"));
    			g.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
    		} catch (IOException e) {
    			e.printStackTrace();
     
    		}
    	}               
    }

  18. #18
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Le délai initial d'une action dans un timer est le délai entre chaque action, ici donc 1 seconde, d'où une latence d'une seconde.

    Soit tu initialises ta frame avec l'image qui correspond à l'état inverse de la première action (le pannel 2 donc)... soit tu mets à un délai initial de 0 par timer.setInitialDelay(0);, (tu peux avoir un tout petit délai normalement non visible, sauf si ta machine rame, puisque tu affiches ta frame avant de lancer le timer.)
    En plus, j'éviterais de charger l'image dans la méthode paintComponent : fait le avant d'ouvrir la frame.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2014
    Messages : 14
    Points : 6
    Points
    6
    Par défaut
    C'est à dire ? Qu'est-ce que vous entendez par avant d'ouvrir la JFrame ?

  20. #20
    Membre éprouvé
    Avatar de Cafeinoman
    Homme Profil pro
    Couteau suisse d'une PME
    Inscrit en
    Octobre 2012
    Messages
    628
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Couteau suisse d'une PME

    Informations forums :
    Inscription : Octobre 2012
    Messages : 628
    Points : 1 256
    Points
    1 256
    Par défaut
    Par exemple, dans ta classe panneau, tu modifie la méthode pour qu'elle prenne une image en paramètre plutôt que de charger l'image. E
    nsuite tu créé une classe ChargeurImage que tu instancie avant ta JFrame. A l'intérieur, tu mets X champs static File, un par image, ou tu fait une Enum, et tu charge les images à l'instanciation.
    Pour finir, tu modifie fenêtre : tu instancie Panneau et tu le declare comme contentPane avant le ActionListener, et dans le switch, tu remplace par panneau.setImage(ChargeurImage.image1).paint();
    Ca t'évite de faire de l'IO dans tes composants graphique, ainsi qu'un certain nombre d'instanciation inutiles d'un même objet.
    «Dieu ne joue pas aux dés.» - Albert Einstein. Et pan! 30 ans de retard dans la théorie quantique!
    «Tout n'est pas politique, mais la politique s'intéresse à tout.» - Nicolas Machiavel. Et surtout à ceux qui ne s'y intéressent pas.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Problème avec repaint() et Thread.sleep
    Par fab13 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 12/08/2008, 23h02
  2. [aide]probléme avec l'instruction group by
    Par diden138 dans le forum Bases de données
    Réponses: 4
    Dernier message: 25/05/2007, 07h09
  3. Problème avec une instruction VBA
    Par Jpeg69 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 22/05/2007, 12h58
  4. Problème avec l'instruction IN : 16 bits retournés
    Par HadiNET dans le forum Assembleur
    Réponses: 4
    Dernier message: 11/02/2006, 17h43
  5. Problème avec une instruction OUTER /Postgres
    Par Volcomix dans le forum Langage SQL
    Réponses: 14
    Dernier message: 21/04/2004, 16h56

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