Méthode utilisant ActionListener ET MouseListener [Résolu]

Signaler
Messages postés
6
Date d'inscription
jeudi 11 février 2021
Statut
Membre
Dernière intervention
25 avril 2021
-
Messages postés
6
Date d'inscription
jeudi 11 février 2021
Statut
Membre
Dernière intervention
25 avril 2021
-
Bonjour,

Je découvre en ce moment les interfaces graphiques en JAVA pour un projet, dans lequel je dois créer un logiciel permettant de dessiner des treillis de poutres (ne me demandez pas pourquoi je ne sais malheureusement pas hum hum...)

J'ai donc créé une JFrame qui contient les différents JPanel de mon logiciel, à savoir un panel ou j'affiche le treillis et les différents éléments de dessin, ainsi qu'un panel qui contient mes boutons d'outils de dessin comme 'Créer un Point'.

Cependant je bloque sur le problème suivant : j'aimerais que lorsque l'utilisateur clique sur le bouton 'Créer un Point', le programme attende ensuite le lieu du clic de la souris dans le panel dessin pour placer le point à l'endroit voulu. Seulement, cela m'amène à utiliser, dans la méthode ActionPerformed qui est liée au bouton, la méthode liée au MouseListener et cela ne fonctionne pas car je n'arrive pas à utiliser le MouseEvent dans la méthode d'ActionPerformed, malgré le fait que je parviens à obtenir l'emplacement d'un clic de souris ou des actions sur un bouton mais de manière séparée.

Toute aide serait la bienvenue, notamment si quelqu'un pourrait me conseiller une méthode pour faire passer des informations sur comment faire passer les events d'une classe à une autre

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PanOutil extends JPanel implements ActionListener {

protected JButton cPt, cTerr, supp, eff, depl;
protected JComboBox<String> app, poutre;

public PanOutil(){
setPreferredSize(new Dimension(200, 1000));
setBackground(Color.BLUE);
this.cPt = new JButton("Créer Un Point");
this.cTerr = new JButton("Créer Un Terrain");
this.supp = new JButton("Supprimer un élement");
this.eff = new JButton("Effacer Dernière Action");
this.depl = new JButton("Deplacer un élement");
String[] capp = {"Appuis Simple","Appui Double","Appui Encastré"};
this.app = new JComboBox<String>(capp);
app.setSelectedIndex(2);
String[] cpoutre = {"Poutre Acier","Poutre Bois","Poutre Pierre"};
this.poutre = new JComboBox<String>(cpoutre);
poutre.setSelectedIndex(2);
this.setLayout(new FlowLayout()) ;
this.add(cPt) ;
this.add(cTerr) ;
this.add(supp) ;
this.add(eff) ;
this.add(depl) ;
this.add(app) ;
this.add(poutre) ;
cPt.addActionListener(this);
}

public void actionPerformed(ActionEvent ev) {
if (ev.getSource() == cPt){
System.out.println("Bouton Créer un point activé");
}

}

}


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.MouseInputListener;

import org.w3c.dom.events.MouseEvent;

public class PanDessin extends JPanel implements MouseInputListener{

public PanDessin(){
this.setBackground(Color.WHITE);
setPreferredSize(new Dimension(1500, 1500));
addMouseListener(this);
}

public void paintComponent(Graphics g) {
super.paintComponent(g);
}

public void dPnt(int x, int y, Graphics g){
g.drawOval(x, y, 10, 10);
g.setColor(Color.BLACK);
}

public void mousePressed(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseReleased(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseEntered(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseExited(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseDragged(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseMoved(java.awt.event.MouseEvent e) {
// TODO Auto-generated method stub

}
public void mouseClicked(java.awt.event.MouseEvent e) {
int x = e.getX();
int y = e.getY();
System.out.println(x +" "+ y);
}


}


import javax.swing.* ;
import java.awt.* ;
import java.awt.event.* ;

public class FenetreDessin extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
private PanOutil po;
private PanDessin pd;
private PanResume pr;

public FenetreDessin(){
this.setTitle("Dessin");
this.setSize(1200,800);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setJMenuBar(new BarreF());
this.setVisible(true);
this.po = new PanOutil();
this.add(po, BorderLayout.WEST);
this.pd = new PanDessin();
this.add(pd, BorderLayout.CENTER);
this.pr = new PanResume();
this.add(pr, BorderLayout.EAST);
}

public void actionPerformed (ActionEvent ev){

}


public static void main(String[] args){
FenetreDessin f = new FenetreDessin();
f.setVisible(true);
}
}





J'ai supprimé du code les quelques essais infructueux qui consistaient à mettre dans la méthode ActionPerformed la méthode MouseClicked ou inversement.

Merci d'avance !

3 réponses

Messages postés
16335
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 mai 2021
2 829
Bonjour,

Lorsqu'un événement est déclenché, il appelle un Listener, et tout est bloqué tant que le Listener n'a pas fini de traiter l’événement. En particulier il n'est pas possible de recevoir un deuxième événement en parallèle, d'où ton problème.
Ce qu'il faut faire, c'est demander au Listener de créer une nouvelle tâche, un SwingWorker, et immédiatement terminer le Listener, sans attendre que la tâche soit terminée. Ce qui permet à la tâche créée de notamment gérer d'autres événements.
Voir https://rom.developpez.com/java-swingworker/

Remarque : ce ne sont pas les JPanel/JFrame qui devraient implémenter les Listener ce qui revient à faire des addListener(this) ce qui est conceptuellement bancal, car this est une fenêtre.
Il vaut mieux faire des classes séparées d'action qui vont implémenter les Listener et que tu vas ensuite ajouter à tes JPanel/JFrame.
Et comme ce sont des classes, tu vas pouvoir hériter d'autres classes, en particulier MouseAdapter qui implémente MouseListener.
Messages postés
6
Date d'inscription
jeudi 11 février 2021
Statut
Membre
Dernière intervention
25 avril 2021
1
Merci beaucoup pour l'aide, ça m'a l'air rudement compliqué et je vais devoir me plonger la dedans. Va falloir redéfinir énormément de choses mais bon, j'avoue être un peu bloqué donc je ne pense pas avoir le choix.

Merci encore !
Messages postés
16335
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
12 mai 2021
2 829
En fait dans ton cas je pense que tu peux t'en sortir simplement.

Tu crées une classe CreerPointListener qui implémente l'ActionListener du bouton et le MouseListener du PanDessin.
Avec un attribut booléen dans la classe que tu initialises à false :
  • quand tu appuies sur le bouton tu le passes à true.
  • quand tu clic sur le dessin tu regardes si le booléen est à false auquel cas tu ne fais rien, par contre s'il est à true tu enregistres la position du point, et tu repasses le booléen à false.
Messages postés
6
Date d'inscription
jeudi 11 février 2021
Statut
Membre
Dernière intervention
25 avril 2021
1
C'est effectivement une solution plus simple, il faut que je regarde ça, ça peut grandement m'arranger.
Merci de la suggestion !