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 :

Toujours Swing et Thread


Sujet :

EDT/SwingWorker Java

  1. #1
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut Toujours Swing et Thread
    Bonjour,
    les habitués du forum vont finir par penser que je suis bouché mais j'ai encore des questions sur Swing et thread malgré la lecture de plusieurs articles ou tutoriels se reportant à cette question.
    Le plus simple est que j'expose mon problème.
    J'utilise javazoom pour lire des mp3 (qui durent entre 30 s et 3 mn, mais leur durée n'a pas d'importance je pense).
    J'ai une interface graphique avec un bouton et une JProgressBar et je veux que l'interface graphique reste opérationnelle pendant la lecture.
    Je voudrai qu'au début de la lecture, le bouton devienne disable puis redevient enable à la fin de la lecture : j'y arrive en plaçant les commandes adéquates avant et après la lecture.
    Mais je voudrai aussi que la JProgressBar indique où j'en suis de ma lecture : c'est cette dernière chose que je n'arrive pas à faire.
    En effet dans tous les exemples que j'ai vu, on utilisais une boucle qui lançait un thread, on récupérait l'indice de la boucle pour faire progresser la JProgressBar mais là je n'ai pas de boucle de lecture.
    C'est en respectant les autres que l'on se fait respecter.

  2. #2
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    Bonjour,
    avec javazoom
    il te faut implémenter l'interface BasicPlayerListener, et tu vas pouvoir agir sur les évènements liés à la lecture :

    Méthodes à implémenter avec l'interface BasicPlayerListener :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    //à l'ouverture du flux
    @Override
    public void opened(Object stream, Map properties)
     
    //pendant la lecture
    @Override
    public void progress(int bytesread, long microseconds, byte[] pcmdata, Map properties)
     
    //En cas de changement d'état
    @Override
    public void stateUpdated(BasicPlayerEvent event)
    Tu as donc de quoi agir sur ta progressBar, avec bytesread par exemple...
    en faisant attention de respecter la gestion des threads de Swing

    Voir Developpeur guide

  3. #3
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    Merci beaucoup je vais essayer cela.
    C'est en respectant les autres que l'on se fait respecter.

  4. #4
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    J'ai laissé de côté pour le moment le problème avec les sons pour me concentrer sur quelque chose de plus facile (normalement) et je n'y arrive toujours pas.

    Il s'agit de faire un diaporama avec des JPanel personnalisés créés à partir d'images (des Cartouches).
    Voici mon 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
    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
     
    public class Diaporama extends JFrame
    {
    	private GestionDonnees gestionDonnees;
    	private int delai = 1000;
    	private JLabel afficheDelai;
    	private Cartouche diaporama;
    	private static JPanel panneauCentral = new JPanel();
    	private JButton plus, moins;
    	private JProgressBar progression;
     
     
    	public Diaporama(GestionDonnees gd)
    	{
    		super("Diaporama");
            this.gestionDonnees = gd;
            this.setSize (800,600);
            this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(null);
     
            JPanel panneauCentral = new JPanel();
            JPanel panneauBas = new JPanel();
     
            progression = new JProgressBar(0,100);
            progression.setPreferredSize(new Dimension(500,20));
            progression.setStringPainted(true);
            plus = new JButton("+");
            String police = plus.getFont().getFontName();
            int taille = 20;
     
            Font font = new Font(police,Font.BOLD,taille);
     
            plus.setFont(font);
            plus.setFocusPainted(false);
     
            moins = new JButton("-");
            moins.setFont(font);
            moins.setFocusPainted(false);
     
    		afficheDelai = new JLabel(1 + " s");
     
    		panneauBas.add(progression);
    		panneauBas.add(plus);
    		panneauBas.add(moins);
    		panneauBas.add(afficheDelai);
     
    		getContentPane().add(panneauBas, BorderLayout.SOUTH);
    		getContentPane().add(panneauCentral,BorderLayout.CENTER);
     
    		setVisible(true);
    		afficher();
    	}
     
    	private void afficher()
    	{
    		System.out.println("afficher");
    		new Thread(new Runnable()
    		{
    			public void run()
    			{
     
    			for (int i = 0 ; i < gestionDonnees.getNbDonnees() ; i++)
    			{
    				System.out.println("image : " + i);
    				String listeImages = gestionDonnees.getImages(i);
    				String nom = gestionDonnees.getNom(i);
    				final ListeImages images = new ListeImages(nom,listeImages);
    					SwingUtilities.invokeLater(new Runnable()
    					{
    						public void run()
    						{
    							System.out.println(images.getNom());
    							Cartouche cartouche = new Cartouche(images);
    							panneauCentral.removeAll();
    							panneauCentral.add(cartouche);
    							panneauCentral.revalidate();
    						}
    					});
    			}
    			}
     
    		}).start();
    	}
     
    	public static void main(String[] args)
    	{
            final GestionDonnees gestionDonnees = new GestionDonnees();
            javax.swing.SwingUtilities.invokeLater(new Runnable() 
            {
                private Diaporama fenetre;
     
    			public void run() 
                {
                	fenetre = new Diaporama(gestionDonnees);
                }
            });
    	}
     
    }
    Et bien sûr rien ne s'affiche. C'est sûrement tout con mais j'y arrive pas. Ceux qui disent que les Thread et SwingWorker c'est facile n'ont jamais été débutants.
    C'est en respectant les autres que l'on se fait respecter.

  5. #5
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    Bonjour,
    heu, je ne veux pas être formaliste, mais le sujet a changé...

    Juste 3 remarques, vite fait :

    • Je ne vois pas à quoi sert le invokeLater du main...puisque tu est dans le main thread
    • Bizarre de ne pas mettre une temporisation entre l'affichage de chaque image... Thread.sleep(tempsEnMilliSec)
    • Quand tu dis que rien ne s'affiche, tu n'as même pas le nom de l'image dans la console ?

  6. #6
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 073
    Points : 7 977
    Points
    7 977
    Par défaut
    Citation Envoyé par kox2ee Voir le message
    [*]Je ne vois pas à quoi sert le invokeLater du main...puisque tu est dans le main thread
    Sous windows builder quand tu crée une application graphique c'est le template de base (en tout cas quand j'essaye sous eclipse) : avoir le main contenant un invokelater avec dedans la creation de la frame et son affichage. Ce n'est pas indispensable mais s'ils le font ainsi il y'a surement une raison
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Citation Envoyé par kox2ee Voir le message

    • Je ne vois pas à quoi sert le invokeLater du main...puisque tu est dans le main thread
    Le main Thread n'est pas l'EDT.
    Or, pour créer des composant swing, il est grandement recommandé de le faire dans l'EDT. D'où l'utilisation de l'invokeLater dans le main.
    Hey, this is mine. That's mine. All this is mine. I'm claiming all this as mine. Except that bit. I don't want that bit. But all the rest of this is mine. Hey, this has been a really good day. I've eaten five times, I've slept six times, and I've made a lot of things mine. Tomorrow, I'm gonna see if I can't have sex with something.

  8. #8
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    C'est effectivement clair, l'EDT n'est pas le main thread...j'ai dit n'importe quoi !
    Mais je prenais pour de la superstition l'utilisation du Invokelater du main.
    Je me pose quelques questions du coup...

    Même sans le InvokeLater initial du main, les appels à Swing (initiaux) se font bien dans l'EDT, et pas dans le thread principal ?
    Et s'il n'y a rien d'autre dans le main que le démarrage de l'interface Swing, comment est-il possible que ces appels ne soient pas theadsafe ?

  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
    Citation Envoyé par Patrice Henrio Voir le message
    Ceux qui disent que les Thread et SwingWorker c'est facile n'ont jamais été débutants.
    Pour ce que j'en juge de ton code, pourtant, tu as très bien compris cette partie là

    Ton problème peux être à plusieurs endroits:
    1) ta boucle n'a pas de temporisation => Tu ne vois rien défiler, juste l'état "final" en sortie de boucle.

    2) gestionDonnees.getNbreDonnees() renvoie 0?

    3) La class "Cartouche" n'affiche rien


    Commence par remplacer dans ta boucle Cartouche par un "new JLabel("Element n°"+i)" et mettre un Thread.sleep(1000) dans la boucle.

  10. #10
    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
    Citation Envoyé par kox2ee Voir le message
    Même sans le InvokeLater initial du main, les appels à Swing (initiaux) se font bien dans l'EDT, et pas dans le thread principal ?
    Non

    Et s'il n'y a rien d'autre dans le main que le démarrage de l'interface Swing, comment est-il possible que ces appels ne soient pas theadsafe ?
    Le tout premier appel pourrait être considéré comme threadsafe dans le sens ou l'EDT n'est pas encore démarré. Mais une fenêtre, ce n'est jamais un composant isolé. Il y a des boutons, des Panels, des menus, des popups et le UI manager. Bien que je n'ai jamais vu d'application "casser" sur une new JFrame() dans le main, ce n'est pas garantis. Le look and feel substance, par exemple, prend un malin plaisir à lancer des IllegalStateException pour tout opération faite en dehors de l'EDT. La doc de swing dit "toute manipulation d'un composant graphique doit être faites dans l'EDT", il vaut mieux respecter la SPEC.

  11. #11
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    C'est indéniable, il vaut mieux respecter la spec, et éviter les potentielles erreurs inexplicables qui ont toujours une explication ( et qu'on attribue la plupart du temps au concepteurs des APIs utilisées ).

    Je copierai 100 fois :
    Tu devras utiliser le SwingUtilities.invokeLater dans ton main pour démarrer ta GUI Swing
    ou j'utiliserai les templates windows Builder...

    Merci ;-)

  12. #12
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    Citation Envoyé par kox2ee Voir le message
    Bonjour,
    heu, je ne veux pas être formaliste, mais le sujet a changé...

    Juste 3 remarques, vite fait :

    • Je ne vois pas à quoi sert le invokeLater du main...puisque tu est dans le main thread
    • Bizarre de ne pas mettre une temporisation entre l'affichage de chaque image... Thread.sleep(tempsEnMilliSec)
    • Quand tu dis que rien ne s'affiche, tu n'as même pas le nom de l'image dans la console ?
    Merci de t'intéresser au sujet. Ce qui a changé c'est ce que je veux faire mais ça reste en lien avec thread et Swing je pense.
    Les affichages dans la console fonctionnent.
    Je pensais que le invokeLater de SwingUtilities mettait justement la ou les instructions suivantes dans l'EDT. Je sais pour l'avoir lu que la plupart des composants graphiques ne nécessitent pas de passer par là car leur création se fait nécessairement dans l'EDT mais j'avais lu aussi que c'était une bonne pratique de traiter tout ce qui concerne Swing dans l'EDT, d'où ce invokeLater.
    Je viens de voir que d'autres ont répondu à cette question du invokeLater.
    C'est en respectant les autres que l'on se fait respecter.

  13. #13
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    Citation Envoyé par tchize_ Voir le message
    Pour ce que j'en juge de ton code, pourtant, tu as très bien compris cette partie là

    Ton problème peux être à plusieurs endroits:
    1) ta boucle n'a pas de temporisation => Tu ne vois rien défiler, juste l'état "final" en sortie de boucle.

    Non cela prend du temps donc ce ne serait pas lié à un affichage trop rapide. De plus j'ai essayé avec un Thread.sleep(delai) et ça n'a rien changé.

    2) gestionDonnees.getNbreDonnees() renvoie 0?
    Non car dans la console j'ai bien les affichages liés à la boucle
    System.out.println("image : " + i);


    3) La class "Cartouche" n'affiche rien
    le cartouche est bien créé puisque l'on peut accéder à sa méthode getNom() qui renvoie le thème des images du cartouche. Par contre quand j'affiche getBounds on me renvoie en effet (0,0,0,0). Comment faire en sorte que le cartouche ait le temps de se construire avant de l'afficher ?


    Commence par remplacer dans ta boucle Cartouche par un "new JLabel("Element n°"+i)" et mettre un Thread.sleep(1000) dans la boucle.
    J'ai modifié légèrement. J'ai rajouté un Thread.sleep().
    Au lieu de vider le panneau central de ses composants (panneauCentral.removeAll()) puis d'ajouter le nouveau cartouche, j'ai fait de ce cartouche un attribut de la classe et sa "valeur" change dans la boucle.
    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
    package jeux.memory.images;
     
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Font;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;
     
    public class Diaporama extends JFrame
    {
    	private GestionDonnees gestionDonnees;
    	private int delai = 1000;
    	private JLabel afficheDelai;
    	private Cartouche cartouche;
    	private static JPanel panneauCentral = new JPanel();
    	private JButton plus, moins;
    	private JProgressBar progression;
     
     
    	public Diaporama(GestionDonnees gd)
    	{
    		super("Diaporama");
            this.gestionDonnees = gd;
            this.setSize (800,600);
            this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(null);
     
            JPanel panneauCentral = new JPanel();
            JPanel panneauBas = new JPanel();
     
            progression = new JProgressBar(0,100);
            progression.setPreferredSize(new Dimension(500,20));
            progression.setStringPainted(true);
            plus = new JButton("+");
            String police = plus.getFont().getFontName();
            int taille = 20;
     
            Font font = new Font(police,Font.BOLD,taille);
     
            plus.setFont(font);
            plus.setFocusPainted(false);
     
            moins = new JButton("-");
            moins.setFont(font);
            moins.setFocusPainted(false);
     
    //		delai = 3000;
    		afficheDelai = new JLabel(delai + " s");
     
    		panneauBas.add(progression);
    		panneauBas.add(plus);
    		panneauBas.add(moins);
    		panneauBas.add(afficheDelai);
     
    		cartouche = new Cartouche();
    		panneauCentral.add(cartouche);
     
    		getContentPane().add(panneauBas, BorderLayout.SOUTH);
    		getContentPane().add(panneauCentral,BorderLayout.CENTER);
     
    		setVisible(true);
    		afficher();
    	}
     
    	private void afficher()
    	{
    		System.out.println("afficher");
    		new Thread(new Runnable()
    		{
    			public void run()
    			{
    				for (int i = 0 ; i < gestionDonnees.getNbDonnees() ; i++)
    				{
    					//System.out.println("image : " + i);
    					String listeImages = gestionDonnees.getImages(i);
    					String nom = gestionDonnees.getNom(i);
    					final ListeImages images = new ListeImages(nom,listeImages);
    					SwingUtilities.invokeLater(new Runnable()
    					{
    						public void run()
    						{
    							//System.out.println(images.getNom());
    							cartouche = new Cartouche(images);
    							cartouche.revalidate();
    							System.out.println(images.getNom() + " " + cartouche.getBounds());
    							panneauCentral.revalidate();
    						}
    					});
    					try
    					{
    						Thread.sleep(delai);
    					}
    					catch (InterruptedException e)
    					{
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    				}
    			}
     
    		}).start();
    	}
     
    	public static void main(String[] args)
    	{
            final GestionDonnees gestionDonnees = new GestionDonnees();
            javax.swing.SwingUtilities.invokeLater(new Runnable() 
            {
                private Diaporama fenetre;
     
    			public void run() 
                {
                	fenetre = new Diaporama(gestionDonnees);
                }
            });
    	}
    }
    Je joins aussi le code de la classe Cartouche.
    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
    package jeux.memory.images;
     
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.FontMetrics;
     
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.border.Border;
    import javax.swing.border.TitledBorder;
     
    public class Cartouche extends JPanel
    {
    	private String nom;
        public Cartouche (ListeImages listeImages)
        {
            this.setLayout (new FlowLayout());
     
            //les images
            for (ImageIcon image : listeImages.getListeImages ())
            {
                this.add (new JLabel(image));
            }
     
            //le titre du cartouche
            nom = listeImages.getNom ();
     
            //la bordure
            Border bf = BorderFactory.createLineBorder(Color.black);
            TitledBorder bordure = BorderFactory.createTitledBorder(bf,nom);
            bordure.setTitleJustification(TitledBorder.CENTER);
            this.setBorder (bordure);
     
            //la taille du composant
            FontMetrics fm = this.getFontMetrics (bordure.getTitleFont());
            int largeurNom = fm.stringWidth (nom) + 20;
            Dimension d = this.getPreferredSize ();
            int largeur =  d.width;
            int hauteur = d.height;
            largeur = Math.max (largeurNom, largeur);
     
            this.setPreferredSize (new Dimension(largeur,hauteur));
        }
     
        public Cartouche()
    	{
    		super();
    		this.setPreferredSize(new Dimension(250,250));
    		this.setBackground(Color.ORANGE);
    	}
     
    	public String getNom()
        {
        	return nom;
        }
     
    }
    ça ne marche toujours pas.
    C'est en respectant les autres que l'on se fait respecter.

  14. #14
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    Bonsoir,
    je n'ai pas trouvé la ligne de code où tu ajoutes ton instance de Cartouche (JPanel) créée à l'intérieur de ta boucle à un conteneur graphique (du genre panneauCentral.add(cartouche))...
    Donc c'est normal que tu ne voies rien se passer graphiquement

    Mais c'est surtout bizarre de créer autant de JPanels que de fois où tu vas passer dans ta boucle...
    donc je crois que l'instanciation de Cartouche est en trop dans la boucle, et qu'il serait préférable d'utiliser toujours la même instance de cartouche pour la mettre à jour en lui faisant un setListImage

  15. #15
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    ligne 61 panneauCentral.add(cartouche);

    Je pensais que cartouche = new Cartouche(), anihilais le précédent. En fait j'ai des images regroupées par thème et je crée un composant descendant de JPanel avec toutes les images d'un même thème. Voir le code de la classe cartouche.
    Comment ferais-tu ?

    Je viens de relire ta réponse, j'ajoute le Cartouche dans le panneau central dans la création de la fenêtre et je modifie ce cartouche dans la boucle.
    En fait il me faudrait plutôt une méthode du type setImages qui modifierais les images du panneau mais cela revient à le reconstruire.
    remarque c'est un peu ce que l'on fait avec un JLabel
    C'est en respectant les autres que l'on se fait respecter.

  16. #16
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    J'avais pas vu la fin de la réponse de Tchize. Je vais déjà essayé avec un JLabel. Donc dans le deuxième code je remplace mon cartouche par un JLabel dans lequel je place la première image de la liste.
    Et ça marche donc je vais creuser vers setImages pour le composant Cartouche.
    C'est en respectant les autres que l'on se fait respecter.

  17. #17
    Membre confirmé
    Homme Profil pro
    Ed Nat
    Inscrit en
    Janvier 2013
    Messages
    325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Ed Nat
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Janvier 2013
    Messages : 325
    Points : 559
    Points
    559
    Par défaut
    oui, ton new Cartouche(...) dans la boucle instancie un nouveau JPanel qui n'est disposé graphiquement nulle part... et ne remplace nullement le précédent.

    Donc il vaut mieux ne pas en instancier un nouveau, mais mettre à jour l'existant.

    Pour résumer :
    • tu instancies ton Cartouche une seule fois, et tu l'ajoutes dans panneauCentral avant la boucle.
    • tu le mets à jour dans la boucle avec un setListImages(...)

  18. #18
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    Citation Envoyé par kox2ee Voir le message
    oui, ton new Cartouche(...) dans la boucle instancie un nouveau JPanel qui n'est disposé graphiquement nulle part... et ne remplace nullement le précédent.

    Donc il vaut mieux ne pas en instancier un nouveau, mais mettre à jour l'existant.

    Pour résumer :
    • tu instancies ton Cartouche une seule fois, et tu l'ajoutes dans panneauCentral avant la boucle.
    • tu le mets à jour dans la boucle avec un setListImages(...)
    Nos messages ce sont croisés.
    Merci.
    C'est en respectant les autres que l'on se fait respecter.

  19. #19
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut
    Bon ça marche. Il me reste à faire avancer la barre de progression au fur et à mesure de l'affichage des images.
    A la fin j'hésite entre redémarrer au début ou arrêter simplement le diaporama ?
    Le code du diaporama
    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
    package jeux.memory.images;
     
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Font;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;
     
    public class Diaporama extends JFrame
    {
    	private GestionDonnees gestionDonnees;
    	private int delai = 1000;
    	private JLabel afficheDelai;
    	private Cartouche cartouche;
    	private static JPanel panneauCentral = new JPanel();
    	private JButton plus, moins;
    	private JProgressBar progression;
    	private JLabel test;
     
     
    	public Diaporama(GestionDonnees gd)
    	{
    		super("Diaporama");
            this.gestionDonnees = gd;
            this.setSize (800,600);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    //        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(null);
     
            JPanel panneauCentral = new JPanel();
            JPanel panneauBas = new JPanel();
     
            progression = new JProgressBar(0,100);
            progression.setPreferredSize(new Dimension(500,20));
            progression.setStringPainted(true);
            plus = new JButton("+");
            String police = plus.getFont().getFontName();
            int taille = 20;
     
            Font font = new Font(police,Font.BOLD,taille);
     
            plus.setFont(font);
            plus.setFocusPainted(false);
     
            moins = new JButton("-");
            moins.setFont(font);
            moins.setFocusPainted(false);
     
    //		delai = 3000;
    		afficheDelai = new JLabel(delai + " s");
     
    		panneauBas.add(progression);
    		panneauBas.add(plus);
    		panneauBas.add(moins);
    		panneauBas.add(afficheDelai);
     
    		String liste = gestionDonnees.getImages(0);
    		String nom = liste.split(";")[0];
    		ListeImages listeImages = new ListeImages(nom,liste,800);
    		cartouche = new Cartouche(listeImages);
    		panneauCentral.add(cartouche);
     
    		getContentPane().add(panneauBas, BorderLayout.SOUTH);
    		getContentPane().add(panneauCentral,BorderLayout.CENTER);
     
    		setVisible(true);
    		afficher();
    	}
     
    	private void afficher()
    	{
    		new Thread(new Runnable()
    		{
    			public void run()
    			{
    				for (int i = 1 ; i < gestionDonnees.getNbDonnees() ; i++)
    				{
    					try
    					{
    						Thread.sleep(delai);
    					}
    					catch (InterruptedException e)
    					{
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					String listeImages = gestionDonnees.getImages(i);
    					String nom = gestionDonnees.getNom(i);
    					final ListeImages images = new ListeImages(nom,listeImages,800);
    					SwingUtilities.invokeLater(new Runnable()
    					{
    						public void run()
    						{
    							cartouche.modifieImages(images);
    							cartouche.revalidate();
    							panneauCentral.revalidate();
    						}
    					});
    				}
    			}
     
    		}).start();
    	}
     
    	public static void main(String[] args)
    	{
            javax.swing.SwingUtilities.invokeLater(new Runnable() 
            {
                private Diaporama fenetre;
     
    			public void run() 
                {
                	fenetre = new Diaporama(new GestionDonnees());
                }
            });
    	}
    }
    Le code de la classe cartouche
    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
    package jeux.memory.images;
     
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.Font;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.SwingUtilities;
     
    public class Diaporama extends JFrame
    {
    	private GestionDonnees gestionDonnees;
    	private int delai = 1000;
    	private JLabel afficheDelai;
    	private Cartouche cartouche;
    	private static JPanel panneauCentral = new JPanel();
    	private JButton plus, moins;
    	private JProgressBar progression;
    	private JLabel test;
     
     
    	public Diaporama(GestionDonnees gd)
    	{
    		super("Diaporama");
            this.gestionDonnees = gd;
            this.setSize (800,600);
            this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    //        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
            this.setLocationRelativeTo(null);
     
            JPanel panneauCentral = new JPanel();
            JPanel panneauBas = new JPanel();
     
            progression = new JProgressBar(0,100);
            progression.setPreferredSize(new Dimension(500,20));
            progression.setStringPainted(true);
            plus = new JButton("+");
            String police = plus.getFont().getFontName();
            int taille = 20;
     
            Font font = new Font(police,Font.BOLD,taille);
     
            plus.setFont(font);
            plus.setFocusPainted(false);
     
            moins = new JButton("-");
            moins.setFont(font);
            moins.setFocusPainted(false);
     
    //		delai = 3000;
    		afficheDelai = new JLabel(delai + " s");
     
    		panneauBas.add(progression);
    		panneauBas.add(plus);
    		panneauBas.add(moins);
    		panneauBas.add(afficheDelai);
     
    		String liste = gestionDonnees.getImages(0);
    		String nom = liste.split(";")[0];
    		ListeImages listeImages = new ListeImages(nom,liste,800);
    		cartouche = new Cartouche(listeImages);
    		panneauCentral.add(cartouche);
     
    		getContentPane().add(panneauBas, BorderLayout.SOUTH);
    		getContentPane().add(panneauCentral,BorderLayout.CENTER);
     
    		setVisible(true);
    		afficher();
    	}
     
    	private void afficher()
    	{
    		new Thread(new Runnable()
    		{
    			public void run()
    			{
    				for (int i = 1 ; i < gestionDonnees.getNbDonnees() ; i++)
    				{
    					try
    					{
    						Thread.sleep(delai);
    					}
    					catch (InterruptedException e)
    					{
    						// TODO Auto-generated catch block
    						e.printStackTrace();
    					}
    					String listeImages = gestionDonnees.getImages(i);
    					String nom = gestionDonnees.getNom(i);
    					final ListeImages images = new ListeImages(nom,listeImages,800);
    					SwingUtilities.invokeLater(new Runnable()
    					{
    						public void run()
    						{
    							cartouche.modifieImages(images);
    							cartouche.revalidate();
    							panneauCentral.revalidate();
    						}
    					});
    				}
    			}
     
    		}).start();
    	}
     
    	public static void main(String[] args)
    	{
            javax.swing.SwingUtilities.invokeLater(new Runnable() 
            {
                private Diaporama fenetre;
     
    			public void run() 
                {
                	fenetre = new Diaporama(new GestionDonnees());
                }
            });
    	}
    }
    C'est en respectant les autres que l'on se fait respecter.

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

Discussions similaires

  1. [Freeze Swing et Threads] Freeze lors d'un appel
    Par Tuxico dans le forum EDT/SwingWorker
    Réponses: 1
    Dernier message: 02/11/2008, 15h53
  2. Problème SWING et Threads
    Par CamilleH dans le forum AWT/Swing
    Réponses: 14
    Dernier message: 12/06/2008, 11h19
  3. Swing et thread
    Par trax44 dans le forum EDT/SwingWorker
    Réponses: 37
    Dernier message: 22/06/2006, 12h10
  4. Réponses: 6
    Dernier message: 27/10/2005, 12h58
  5. [SWING][THREAD]Méthodes pour afficher une Frame
    Par pompidouwa dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 05/05/2004, 10h35

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