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 :

Déplacer un JPanel avec un Timer


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti Avatar de mimievan
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 25
    Par défaut Déplacer un JPanel avec un Timer
    Salut à tous! Voilà mon problème, j'utilise Timer et le JPanel se déplace mais sort de l'écran. Or je ne veux le déplacer qu'à une position bien définie. Voilà 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
     
    public void move(){
    		Dimension size = this.getPreferredSize();
    		setBounds(position_x, position_y, size.width, size.height);
    		Timer tm = new Timer(6,new ActionListener() {
                public void actionPerformed(ActionEvent e) {
    				int i=0;
                    while( i<5){
    				position_x++;
    				position_y--;
    				i++;
    				if(i==5){break;}
                }
            }});
            tm.start();
     
     
     
     
    	}

  2. #2
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Tu peux nous montrer un code plus complet, parce que je ne vois rien ici qui bougerait un JPanel dans un Timer. Tout ce que je vois c'est une méthode qui change la position d'un composant (je suppose qu'il s'agit du JPanel) à un endroit désigné par position_x et position_y, et qui lance une action qui toutes les 6 ms fait une boucle inutile pour incrémenter position_x de 5 et décrémenter position_y de 5.


    Par ailleus, le if(i==5){break;} est inutile à la fin d'un bloc while(i<5), parce que redondant.
    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.

  3. #3
    Membre averti Avatar de mimievan
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 25
    Par défaut Voilà les class où je compte utiliser pour le Timer
    Merci pour la réponse.
    Donc voilà :
    /*/Class Essai où on appelle la class ballon/*/
    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
     
    public class Essai extends JPanel{
    	final MonJSlide puissance = new MonJSlide(100, 0, 0, 10, 20);
    	final MonJSlide degre = new MonJSlide(180, 0, 0, 15, 30);
    	final Ballon ball = new Ballon();
     
    	public Essai(){
    		JLabel lab_h = new JLabel();
    		String h = "D:/Rugby/h.png";
     
    		JLabel instruction = new JLabel("Instructions");
    		JLabel instruction0 = new JLabel("- Choisissez la puissance de votre tir.");
    		JLabel instruction1 = new JLabel("- Choisissez le degre du tir ");
    		JLabel instruction2 = new JLabel("- Cliquez sur le ballon pour faire un essai ");
    		JLabel instruction3 = new JLabel("- Attention, choisissez bien vos valeurs!!! ");
     
    		setLayout(null);
     
    		insertImage(lab_h,h);
    		Dimension size = lab_h.getPreferredSize();
    		lab_h.setBounds(0,0,
            size.width, size.height);
     
     
    		size = ball.getPreferredSize();
    		ball.setBounds(343,480,
            size.width, size.height);
    		ball.tirerDrop(puissance.getIndice(),degre.getIndice());
    		ball.setFocusable(true);
     
     
    		size = puissance.getPreferredSize();
    		puissance.setBounds(830,360,
            size.width, size.height);
     
    		size = degre.getPreferredSize();
    		degre.setBounds(830,300,
            size.width, size.height);
     
     
    		add(ball);
    		add(lab_h);
    		add(degre);
    		add(puissance);
     
     
     
    	}
    	public void insertImage(JLabel contenant_image, String path_name){
    		ImageIcon icon = new ImageIcon(path_name);
    		contenant_image.setIcon(icon);
    	}
    }
    La Class Ballon
    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
     
    public class Ballon extends JPanel{
    	int force = 10;
    	int degre;
    	int position_x = 343;
    	int position_y = 480;
     
        public Ballon(){
    		JLabel lab_ball = new JLabel();
    		String ball = "D:/Rugby/ballon.png";
    		ImageIcon icon = new ImageIcon(ball);
    		lab_ball.setIcon(icon);
    		add(lab_ball);
    	}
     
    	public void tirerDrop(int force, int degre){
    		this.addMouseListener(new EssaiListener(this));
    	}
     
    	public void move(){
    		Dimension size = this.getPreferredSize();
    		setBounds(position_x, position_y, size.width, size.height);
    		Timer tm = new Timer(6,new ActionListener() {
                public void actionPerformed(ActionEvent e) {
    				int i=0;
                    while( i<5){
    				position_x++;
    				position_y--;
    				i++;
                }
            }});
            tm.start();	
    	}	
    }
    Et le Listener de la Class Ballon et Essai

    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
     
    public class EssaiListener implements MouseListener{
    	Ballon balle;
     
        public EssaiListener(Ballon ball){
    		balle = ball;
    		ball = balle;
    	}
     
    	public void mouseClicked( MouseEvent e )
        {
    		balle.move();
     
        }
    	public void mousePressed(MouseEvent e){	
    	}
    	public void mouseReleased(MouseEvent e){
    	}
    	public void mouseEntered(MouseEvent e){
    	}
    	public void mouseExited(MouseEvent e){
    	}
    }
    J'espère que tu vois où je veux en venir. Et merci d'avance.

  4. #4
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Je comprends mieux maintenant ce que tu cherches à faire. Et ce n'est pas du tout ce que fait ton code.

    Premièrement, il semble que tu veuilles lorsqu'on clique sur le ballon, que celui-ci se déplace progressivement (animation). C'est bien avec un Timer qu'il faut faire ça, mais l'action du Timer doit :
    1. modifier les coordonnées pour un déplacement : le timer va appeler l'action plusieurs fois, toutes les 6 ms (le paramètre delay). Donc, à chaque appel, on déplace un tout petit peu le ballon, et cumulé, le ballon sera déplacé d'autant de fois que l'action aura été appelée multiplié par la valeur de l'incrément ou décrément des coordonnées. A chaque fois que les variables qui te servent de coordonnées change, il faut les réappliquer, sinon il n'y a aucun raison pour que le composant change de position. Avec ton code, il change de position à chaque clic, mais en plus ça relance un timer qui ne fait que modifier les coordonnées. Les timers s'accumulent (5 clics = 5 timers), qui tous modifient les coordonnées, qui très vite vont sortir de la frame.
    2. ensuite, il faut que le ballon s'arrête à un moment donné, donc que le timer s'arrête à un moment donné (ce qui se fait par tm.stop()). Il te faut donc avoir une condition qui arrête le timer : soit par exemple en comparant la nouvelle position obtenue à chaque action, avec des limites (celles du panel). Il faudrait également empêcher de relancer un timer lorsque l'animation est en cours, pour éviter de cumuler les timers (on peut par exemple faire setEnable(false).
    3. de la même manière, il ne faut pas ajouter le mouseListener dans une méthode qu'on pourrait appeler plusieurs fois : une seule fois suffit, sinon ça va cumuler les appels (si tu as 2 mouseListners, chacun va appeler move(), donc ça va lancer 2 timers (le ballon se déplacera en théorie 2 fois plus vite : en pratique, ça va forcément pas forcément être le cas pour des raisons que je n'expliquerais pas en détail (voir les notions de synchronisation, volatile, si ça t’intéresse)). En bref, ça va faire n'importe quoi : autant ne pas le faire.


    A noter par ailleurs, que tu ne devrais pas charger le fichier image avec un chemin en dur (afin de pouvoir par la suite distribuer ton programme sans forcer ceux à qui tu le donnes d'avoir un lecteur d: avec un dossier Rugby (ce qui sera de toute manière impossible pour qui utilise linux ou un mac).

    Exemple :

    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
    public class Ballpanel extends JPanel {
     
    	private static final ImageIcon IMAGE_ICON = new ImageIcon(Ballpanel.class.getResource("ballon.png")); // mettre le fichier dans le même dossier/package que la classe
    	private Timer timer;
    	private final JLabel ball;
    	private final int startPos; 
     
    	public Ballpanel(final int posx) { 
    		super(true);
    		this.startPos = posx;
    		setLayout(null);
    		ball = new JLabel(IMAGE_ICON);
    		ball.setSize(IMAGE_ICON.getIconWidth(), IMAGE_ICON.getIconHeight());
    		add(ball);
    		// quand on clique sur le ballon, il part
    		ball.addMouseListener(new MouseAdapter() {
    			@Override
    			public void mouseClicked(MouseEvent e) { 
    				startMoveBall();
    			}
    		});
    		// lorsqu'on clic dans le panel, on remet le ballon à sa place de départ
    		addMouseListener(new MouseAdapter() {
     
    			@Override
    			public void mouseClicked(MouseEvent e) {
    				resetBall();
    			}
    		});
    		// place la ballon en bas du panel
    		addComponentListener(new ComponentAdapter() {
    			@Override
    			public void componentResized(ComponentEvent e) {
    				resetBall();
    			}
    		});
    	}
     
    	/**
             * Remet la balle à sa place de départ
             */
    	public void resetBall() {
    		if ( timer==null ) {
    			ball.setLocation(startPos, getHeight()-IMAGE_ICON.getIconHeight());
    		}
    	} 
     
    	public void stopBall() {
    		if ( timer!=null ) {
    			if ( timer!=null ) {
    				timer.stop();
    				timer=null;
    			}
    		}
    	}
     
    	private void startMoveBall() { 
    		if ( timer==null ) {
    			timer = new Timer(15, e-> moveBall());
    			timer.start();
    		}
    	}
     
    	private void moveBall() {
    		if ( timer==null ) return; // évite que si une action est demandée alors que le timer a été mis à null, ça plante
    		Point location = ball.getLocation(); // position actuelle
    		// on fait le déplacement
    		location.x+=5;
    		if ( (getWidth()-location.x)>(getWidth()-startPos)/2 ) {
    			location.y-=3; // bidon (il faudrait un mouvement parabolique)
    		}
    		else {
    			location.y+=3; // bidon (il faudrait un mouvement parabolique)
    		}
    		ball.setLocation(location); // on applique le déplacement
    		if ( location.x>getWidth() ) {
    			// lorsque la balle dépasse à droite, on arrête le déplacement
    			timer.stop();
    			timer=null;
    		}
    	}
     
    	public static void main(String[] args) {
     
    		JFrame frame = new JFrame("Exemple");
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		frame.add(new Ballpanel(30));
     
    		frame.setSize(600, 400);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
    	}
     
    }
    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.

  5. #5
    Membre averti Avatar de mimievan
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2015
    Messages : 25
    Par défaut
    Donc je n'ai plus besoin de la class EssaiListener si je veux l'utiliser dans mon projet?

  6. #6
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par mimievan Voir le message
    Donc je n'ai plus besoin de la class EssaiListener?
    Ça, c'est à toi de voir : moi j'ai utilisé une classe anonyme, parce qu'il n'y avait pas grand chose dans la redéfinition, et pas besoin de réusabilité, mais on peut faire une classe interne, ou externe, si on veut (pour peu qu'on veuille gérer plusieurs ballons pourquoi pas).
    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.

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

Discussions similaires

  1. Déplacer un GroupBox avec un Timer
    Par Pouknouki dans le forum VB.NET
    Réponses: 3
    Dernier message: 20/04/2012, 18h29
  2. [C#] Déplacer un composant avec la souris
    Par GéniuS77 dans le forum Windows Forms
    Réponses: 8
    Dernier message: 07/04/2011, 23h12
  3. Interchanger un JPanel avec un autre
    Par jfz dans le forum Agents de placement/Fenêtres
    Réponses: 10
    Dernier message: 09/01/2010, 20h38
  4. [Swing] JPanel avec sa JScrollBar qui scrolle toute seule
    Par chcoust dans le forum AWT/Swing
    Réponses: 5
    Dernier message: 22/11/2006, 14h37
  5. Déplacer un panel avec la souris
    Par Harry dans le forum Delphi
    Réponses: 14
    Dernier message: 05/06/2006, 19h18

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