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 :

comment déplacer un objet avec la souris


Sujet :

AWT/Swing Java

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2013
    Messages : 9
    Points : 8
    Points
    8
    Par défaut comment déplacer un objet avec la souris
    Bonsoir,

    Je suis débutante en JAVA, et je cherche à implémenter un jeu qui consiste à déplacer des moitiés de figures pour reformer les figures entières.
    Mon problème est de trouver un moyen pour que lorsque l'on clique sur un objet celui-ci soit fixé à la souris, qu'il se déplace avec elle, et une fois qu'on reclique il faudrait que l'objet se dépose. J'ai fais des recherches mais ça part un peu dans tous les sens, si l'un d'entre vous pourrait m'indiquer une marche à suivre la plus simple possible ce serait merveilleux,
    J'ai pour l'instant créer une fenêtre avec un bouton, mais je ne vois pas comment prendre en compte l'action de la Souris sur le bouton, je sais qu'il faut utiliser des MouseListener, mais le codage de tout est très confus pour moi, je ne sais pas par où commencer ni s'il faut utiliser un drag'n drop ou même s'il faut creér un ou plusieurs panels... en gros je suis complètement perdue, votre aide sera la bienvenue, merci d'avance.

  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 : 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,

    Il te faudra utiliser en complément du MouseListener , un MouseMotionListener pour pouvoir réagir aux mouvements de la souris. La classe MouseMotionAdapter combine déjà ces deux écouteurs. Ensuite, il faut prendre en compte les coordonnées relatives du composant déplacé par rapport aux coordonnées de la souris. Comme tes composants sont déplaçables à des coordonnées quelquonques, il faudra supprimer le layout manager, qui justement sert à gérer automatiquement les coordonnées (et les tailles) des composants.

    Voici un exemple de principe :

    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
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Container;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
     
    import javax.swing.BorderFactory;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
     
    public class MoveComponents extends JPanel {
     
        public MoveComponents() {
     
            setLayout(null); // on supprime le layout manager
     
            ComponentMove listener = new ComponentMove(this);
            for(int i=0; i<10; i++) {
                add(createComponent());
            }
            addMouseListener(listener);
            addMouseMotionListener(listener);
     
        }
     
        private final static Color[] COLORS= {Color.RED, Color.GREEN, Color.YELLOW, Color.ORANGE, Color.BLUE, Color.CYAN, Color.MAGENTA, Color.PINK, Color.WHITE, Color.BLACK};
     
        private JComponent createComponent() {
            JPanel component=new JPanel(); // ici on peut faire n'importe quel JComponent, JLabel, par exemple
            component.setLocation((int)(Math.random()*100), (int)(Math.random()*100)); // position aléatoire
            component.setSize(10+(int)(Math.random()*100), 10+(int)(Math.random()*100)); // taille aléatoire
            component.setBackground(COLORS[(int)(Math.random()*COLORS.length)]); // couleur aléatoire
            component.setEnabled(false); // les composants ne doivent pas intercepter la souris
            return component;
        }
     
        private static class ComponentMove extends MouseAdapter {
     
            private boolean move;
            private int relx;
            private JComponent component;
            private int rely;
            private Container container;
     
            public ComponentMove(Container container) {
                this.container=container;
            }
     
            @Override
            public void mousePressed(MouseEvent e) {
                if ( move ) {
                    move=false; // arrêt du mouvement
                    component.setBorder(null); // on  supprime la bordure noire
                    component=null;
                }
                else {
                    component = getComponent(e.getX(),e.getY()); // on mémorise le composant en déplacement
                    if ( component!=null ) {
                        container.setComponentZOrder(component,0); // place le composant le plus haut possible
                        relx = e.getX()-component.getX(); // on mémorise la position relative
                        rely = e.getY()-component.getY(); // on mémorise la position relative
                        move=true; // démarrage du mouvement
                        component.setBorder(BorderFactory.createLineBorder(Color.BLACK)); // on indique le composant sélectionné par une bordure noire
                    }
                }
            }
     
            private JComponent getComponent(int x, int y) {
                // on recherche le premier composant qui correspond aux coordonnées de la souris
                for(Component component : container.getComponents()) {
                    if ( component instanceof JComponent && component.getBounds().contains(x, y) ) {
                        return (JComponent)component;
                    }
                }
                return null;
            }
     
            @Override
            public void mouseMoved(MouseEvent e) {
                if ( move ) {
                    // si on déplace
                    component.setLocation(e.getX()-relx, e.getY()-rely);
                }
            }
     
        }
     
        public static void main(String[] args) {
     
            JFrame frame = new JFrame("exemple");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
            frame.setContentPane(new MoveComponents());
     
            frame.setSize(300, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
     
        }
     
    }
    Personnellement, j'utilise une bibliothèque qui me permet de gérer ça beaucoup plus facilement, et beaucoup d'autres choses, qui s'appelle Piccolo2D.
    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
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2013
    Messages : 9
    Points : 8
    Points
    8
    Par défaut
    MERCCIIIIII mille fois!!!!!,
    c'est exactement ce dont j'avais besoin!!!!!
    Tu me sauves!

    je vais étudier attentivement ce code, pour tout comprendre, merci encore!!!

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2013
    Messages : 9
    Points : 8
    Points
    8
    Par défaut problème sur le container
    reBonjour,

    J'essaie d'appliquer le code fourni plus haut à une fenêtre (JFrame) contenant un JPanel qui lui même contient un JLabel,
    pour les components cela ne pose pas de problème car ce sont des JLabel, cependant j'ai un soucis avec le container, enfin je pense que le problème viens de là car lorsque j'applique ce code à cette fenêtre, les JLabels ne bougent pas, auriez-vous une idée?

  5. #5
    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
    Normalement, pas de différence entre des JPanel et des JLabel (ou plus généralement des conteneurs et des composants dans des conteneurs).

    Le seul problème qu'on peut rencontrer, éventuellement, c'est que si on veut pouvoir déplacer les composants et leur conteneur, les composants vont devoir écouter les évènements souris, et donc vont capter ceux qu'on pourrait vouloir écouter dans le conteneur, qui va écouter les mêmes évènements que ses contenus. Autrement dit, c'est le composant le plus haut qui capte les évènements, et celui en-dessous ne peut les capter que la où aucun composant n'est affiché dedans.

    Trois possibilités :

    1) si le conteneur et son contenu sont totalement solidaires (on ne peut pas déplacer un des composants à l'intérieur du conteneur). Dans ce cas, il suffit d'écouter les évènements uniquement sur le conteneur. Seul problème : si le composant contenu à besoin d'avoir une gestion évènementiel, comme pour un JButton, ou pour un JTextField, tu ne pourras pas déplacer ton conteneur lorsque la souris est positionné dans le composant, qui va capter les évènements. Mais avec des JLabel, cela fonctionne très bien.
    2) sinon, si le conteneur et les composants à l'intérieur écoutent tous les évènements (par le même MouseMotionAdapter), on pourra déplacer le conteneur en cliquant dans les "trous" (les endroits du conteneur entre les composants). Les contenus vont suivre, puisque placés relativement au conteneur.
    3) l'alternative à la deuxième solution est d'avoir 2 modes. De nombreuses applications gèrent ça comme ça : un mode qui permet de déplacer les conteneurs, un mode qui permet de déplacer les composants à l'intérieur.

    Accessoirement, lorsque l'interface sort un peu des sentiers battus, le fait d'utiliser des composants d'UI standard comme des JLabel ou des JPanels, s’avèrent souvent moins pratique que de gérer soit même des composants graphiques maison, dessinés dans un canvas, avec gestion des évènements fait soi même. Pour avoir personnellement ce genre d'interface dans l'application professionnelle sur laquelle je travaille, je n'utilise absolument pas les composants standards d'UI. Pour éviter d'avoir à tout réécrire, j'utilise une bibliothèque, appelée Piccolo2D, qui me permet de gérer ce genre de chose (entre autres). Elle ajoute justement des concepts supplémentaires qui n'existe pas en UI SWING standard, qui permet d'indiquer si le contenu est solidaire, ou pas (ou si le conteneur se déplace indépendamment de ses contenus, par exemple), si des évènements doivent être captés par le conteneur, ou transmis au contenu (et à quel contenu...), et, surtout, on peut gérer ça très finement, en fonction des composants, des modifiers (par exemple dire que sur CTRL-DRAG on déplace le contenu, et sur DRAG on déplace le contenant, par exemple), etc. Accessoirement, la bibliothèque m'empêche pas d'utiliser à certains endroits des composants SWING.
    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.

  6. #6
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Santé

    Informations forums :
    Inscription : Mars 2013
    Messages : 9
    Points : 8
    Points
    8
    Par défaut
    merci pour cette réponse, du coup j'aimerais avoir ton avis sur la marche à suivre (utiliser les standard ou plutôt faire ça maison), voici le bout de code que j'ai à ma disposition :
    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
    public class gameWindow extends JPanel implements ActionListener{
     
    	private  JFrame gameWindow;
    	private  JPanel gamePanel;
     
    	private JComponent labelIMG1, labelIMG2, labelIMG3, labelIMG4;
     
    	private ImageIcon imgExit;
    	private JButton btnQuit;
    	private String nameGameWindow;
    	private String level;
     
    	private CImage monImage;
     
     
     
    	public gameWindow(String p_Level){
     
     
    		//creation fenetre
     
    		level = p_Level;
    		nameGameWindow = "Fenetre de jeux";
    		gameWindow = new JFrame();
    		gameWindow.setTitle(nameGameWindow);
    		gameWindow.setSize(800, 800);
    		gameWindow.setLocationRelativeTo(null);
    		gameWindow.setResizable(false);
    		gameWindow.setAlwaysOnTop(true);
    		gameWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		gameWindow.setLayout(null);
     
    		//creation du panel
     
    		gamePanel = new JPanel();
    		gamePanel.setBackground(Color.GRAY);
    		gamePanel.setLocation(800, 800);
    		gamePanel.setLayout(null);
     
    		btnQuit = new JButton();
    		btnQuit.setBounds(600, 600, 128, 128);
    		imgExit = new ImageIcon("img\\config\\exit128.png");
    		btnQuit.setIcon(imgExit);
    		gamePanel.add(btnQuit);
     
    		try {
    			monImage = new CImage("img\\levels\\"+level+"\\1.jpg");
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
     
    		//creation des labels a deplacer
     
    		labelIMG1 = new JLabel(new ImageIcon(monImage.getPart1())); 
    		labelIMG1.setBounds(50, 50, 220, 220);
    		gamePanel.add(labelIMG1);
     
     
    		labelIMG2 = new JLabel(new ImageIcon(monImage.getPart2())); 
    		labelIMG2.setBounds(200, 50, 220, 220);
    		gamePanel.add(labelIMG2);
     
    		try {
    			monImage = new CImage("img\\levels\\"+level+"\\2.jpg");
    		} catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		labelIMG3 = new JLabel(new ImageIcon(monImage.getPart1())); 
    		labelIMG3.setBounds(50, 300, 220, 220);
    		gamePanel.add(labelIMG3);
     
    		labelIMG4 = new JLabel(new ImageIcon(monImage.getPart2())); 
    		labelIMG4.setBounds(200, 300, 220, 220);
    		gamePanel.add(labelIMG4);
     
     
    		btnQuit.addActionListener(this);
     
    	}



    il est plutôt simple, et intuitif mais je n'arrive pas à appliquer le code que tu m'as fourni plus haut à celui la, aurais-tu une idée?

  7. #7
    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
    C'est plutôt difficile de juger avec si peu de code, et sans description globale. Là, tu as 4 images, placées librement dans un panel : d'un côté je me dis que pour si peu, autant ne pas (ré)écrire des composants maison (cela peut être beaucoup de travail, et peut être plus ou moins long à mettre au point), mais d'un autre côté, dessiner 4 images dans un canvas n'est pas collossale, et utiliser des labels juste pour afficher des images dans un panel sans layout est un peu utiliser 3 % des capacités des composants (un peu comme utiliser un bus à 2 étages pour transporter une personne, y compris le chauffeur, pour traverser la rue). En particulier, si le but final est de faire un jeu, dans lequel il pourrait y avoir plus d'images, avec une grande liberté de placement (donc plus ou moins complexe à faire avec un layout, même maison), de l'animation peut être. Le bouton exit pourrait être géré à part dans son propre panel avec layout, avec un canvas spécifique qui affiche des images pour la partie plateau de jeu.

    Par ailleurs, je ne vois aucunement le type de structure dont tu parlais (des composants à déplacer dans un autre composant à déplacer) : donc, soit je n'ai pas compris ce que tu voulais dire, soit ton extrait de code n'est pas assez pertinent.

    Pour appliquer mon exemple à ton code, c'est pourtant assez direct : tu as exactement la même structure que j'ai. Ce que j'ai appelé MoveComponents est le JPanel gamePanel dans ton code. Et au lieu de créer des JComponents dans une boucle, tu créés des JLabel en séquence (penses juste à appeler setEnabled(false) sur ces JLabels) . Ce qui doit te géner, c'est que tu as une classe gameWindow qui étend JPanel, mais que tu n'utilises pas comme panel, mais seulement comme coquille pour initialiser une autre fenêtre (référencée par une variable qui a le même nom que la classe, ce qui ajoute de la confusion) dans laquel tu mets un autre panel 'celui sur lequel appeler :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ComponentMove listener = new ComponentMove(gamePanel);
    gamePanel.addMouseListener(listener);
    gamePanel.addMouseMotionListener(listener);
    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. [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
  2. déplacer un objet avec la souris
    Par pingpong dans le forum OpenGL
    Réponses: 4
    Dernier message: 24/10/2007, 01h54
  3. Déplacer un panel avec la souris
    Par Harry dans le forum Delphi
    Réponses: 14
    Dernier message: 05/06/2006, 19h18
  4. comment tourner la vue avec la souris
    Par delfare dans le forum OpenGL
    Réponses: 13
    Dernier message: 12/09/2004, 17h44

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