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

AWT/Swing Java Discussion :

Deplacement "visuel" d'un JLabel


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 82
    Par défaut Deplacement "visuel" d'un JLabel
    Bonjour,

    j'ai placé au milieu d'un JPanel un JLabel et j'aimerais le voir se deplacer d'un point à un autre lorsque j'actionne une action à l'aide d'un menuitem.

    voici le code que j'ai écrit:
    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
     
    public class Test extends JPanel {
     
    	JLabel p;
     
    	public Test() {
    		setPreferredSize(new Dimension(512, 512));
    		setBackground(Color.WHITE);
    		setLayout(null);
    		p = new JLabel(new ImageIcon("image.gif"));
    		p.setBounds(200, 200, 64, 64);
    		add(p);
    	}
     
    	private void deplacement() {
    		for (int i = 200; i < 400; i++) {
    			p.setLocation(i, i);
    			try {
    				Thread.sleep(5);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
     
    	public static void main(String[] args) {
    		final Test t = new Test();
    		JFrame fenetre = new JFrame();
    		fenetre.getContentPane().setLayout(new BorderLayout());
    		fenetre.getContentPane().add(t, BorderLayout.CENTER);
    		fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JMenuBar menuBar = new JMenuBar();
    		JMenu menu = new JMenu("MENU");
    		JMenuItem item = new JMenuItem("test");
    		item.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent arg0) {
    				t.deplacement();
    			}
    		});
    		menu.add(item);
    		menuBar.add(menu);
     
    		fenetre.setJMenuBar(menuBar);
    		fenetre.pack();
    		fenetre.setVisible(true);
    		t.deplacement();
    	}
     
    }
    le deplacement s'effectue bien lors de la derniere instruction de mon main, je le vois bien se faire à l'ecran.
    par contre, lorsque je l'actionne à l aide du menu, je ne le vois plus, alors qu'il s'effectue bien (si je mets un println dans ma boucle for, je vois dans la console que la boucle s'effectue bien).
    Comment puis-je faire pour forcer l'affichage à chaque passage dans la boucle?

  2. #2
    Membre chevronné Avatar de schniouf
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    382
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2003
    Messages : 382
    Par défaut
    Tout simplement parce que ton traitement "bloque" le rafraichissement de ton appli.
    --> Il faut mettre ce genre de code dans un thread à part, voir ce tutoriel.
    Ca donnerai un truc du genre :

    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
    private void deplacement() {
    new Thread(){
       public void run() {
    	for (int i = 200; i < 400; i++) {
    		SwingUtilities.invokeLater( new Runnable() {
                       public void run() {
                          p.setLocation(i, i);
                       }
                    }
    		try {
    			Thread.sleep(5);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
       }
    }.start() ;
    }
    ++

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 82
    Par défaut
    Merci pour ta réponse, cela fonctionne à présent.
    j'avais bien pensé à cette raison de blocage du rafraîchissement, et j'avais aussi lu ce tutoriel, mais j'avais testé comme ça :
    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
     
    private void deplacement() {
    	new Thread() {
    		public void run() {
    			SwingUtilities.invokeLater(new Runnable() {
    				public void run() {
    					for (int i = 200; i < 400; i++) {
    						p.setLocation(i, i);
    					}
    					try {
    						Thread.sleep(5);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			});
    			}
    	}.start();
    }
    J'ai placé la boucle for dans la méthode run du "invokeLater". et là, ça ne marche pas toujours pas. je vois pas trop pourquoi...
    merci encore pour ta solution.

  4. #4
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Elmilouse
    J'ai placé la boucle for dans la méthode run du "invokeLater". et là, ça ne marche pas toujours pas. je vois pas trop pourquoi...
    Parce que tu effectue le sleep() dans le thread de l'EDT, ce qui fait que ce dernier s'endort au lieu de continuer à gérer l'affichage...


    A noter que tu peux utiliser javax.swing.Timer pour cela, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    	Timer timer = new Timer(5, new ActionListener() {
    		private int i = 200;
    		public void actionPerformed(ActionEvent e) {
    			p.setLocation(i, i);
     
    			if (++i>=400) {
    				Timer timer = (Timer) e.getSource();
    				timer.stop();
    			}
    		}
    	});
     
    	timer.start();

    a++

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    82
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 82
    Par défaut
    Merci, je comprends mon erreur.
    Je vais utiliser ta solution avec la classe Timer.

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

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo