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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    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.

  2. #2
    Membre chevronné
    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
    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 éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    Par défaut
    Merci beaucoup je vais essayer cela.

  4. #4
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    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.

  5. #5
    Membre chevronné
    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
    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
    R&D - Palefrenier programmeur
    Inscrit en
    Août 2006
    Messages
    4 098
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : R&D - Palefrenier programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 098
    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 confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    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.

  8. #8
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    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.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    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
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    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.

+ 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