2011-09-07 2 views
6

J'ai étend la classe whitch JPanel:Déterminez le composant JPanel cliqué dans MouseListener. Gestion des événements

public class ButtonPanel extends JPanel { 

    private label; 

    public ButtonPanel() { 
     label=new JLabel("waiting for click"); 
     add(label); 
    } 

    public void setButtonText() { 
     label.setText("just clicked"); 
    } 

} 

J'ai plusieurs instances de cette classe qui est ajouté à JFrame. Je veux créer une instance de classe MouseAdapter et ensuite les ajouter en tant qu'écouteur souris à tous les composants ButtonPanel sur mon JFrame. Je meen:

ButtonPanel butt1 = new ButtonPanel(); 
ButtonPanel butt2 = new ButtonPanel(); 
ButtonPanel butt3 = new ButtonPanel(); 
//... here goes code which add ButtonPanels to JFrame 

MouseAdapterMod mam = new MouseAdapterMod(); 
butt1.addMouseListener(mam); 
butt2.addMouseListener(mam); 
butt3.addMouseListener(mam); 

La classe MouseAdapterMod Je veux être séparé de l'autre et de localiser dans son propre paquet. Il devrait ressembler à ceci:

public class MouseAdapterMod extends MouseAdapter { 

    public void mouseClicked(MouseEvent e) { 
     //here goes the code of calling setButtonText method of ButtonPanel component on which the event had occurred 
    } 
} 

Le problème est que je ne sais pas comment implémenter la méthode mouseClicked pour le rendre déterminer lequel de panneauBoutons générer l'événement et appeler la méthode correspondant à cette setButtonText() des composants. Est-ce que quelqu'un sait comment faire cela? Je sais que je peux y parvenir en incluant la fonctionnalité de gestion d'événements dans la classe ButtonPanel, mais ce n'est pas approprié pour moi, parce que je veux conserver la structure de classe comme je l'ai décrit ci-dessus et avoir une seule classe de MouseAdapterMod pour gérer tous les ButtonPanels.

+0

Coup de coeur pour votre dernier paragraphe. –

Répondre

14

La méthode MouseEvent#getSource retourne quel objet a été cliqué:

public class MouseAdapterMod extends MouseAdapter { 

    // usually better off with mousePressed rather than clicked 
    public void mousePressed(MouseEvent e) { 
     ButtonPanel btnPanel = (ButtonPanel)e.getSource(); 
     btnPanel.setButtonText(); 
    } 
} 

Comme la note des commentaires, vous êtes souvent mieux écouter pour mousePressed ou mouseReleased plutôt que mouseClicked parce que pour mouseClicked de travailler, la presse et La version doit provenir du même point, et si la souris décale même légèrement, le clic ne sera pas enregistré.

Mon programme d'essai:

import java.awt.Color; 
import java.awt.GridLayout; 
import java.awt.event.*; 

import javax.swing.*; 

public class MainForButtonPanel extends JPanel { 
    public MainForButtonPanel() { 
     setLayout(new GridLayout(4, 4)); 

     MouseAdapter myMA = new MouseAdapterMod(); 

     for (int i = 0; i < 4; i++) { 
     for (int j = 0; j < 4; j++) { 
      ButtonPanel btnPanel = new ButtonPanel(); 
      btnPanel.addMouseListener(myMA); 
      add(btnPanel); 
     } 
     } 

    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("MainForButtonPanel"); 
     frame.getContentPane().add(new MainForButtonPanel()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
     }); 
    } 
} 

class ButtonPanel extends JPanel { 

    private static final int TIMER_DELAY = 2000; 
    private static final String JUST_CLICKED = "just clicked"; 
    private static final String WAITING_FOR_CLICK = "waiting for click"; 
    private static final Color CLICKED_COLOR = Color.pink; 
    private JLabel label; 

    public ButtonPanel() { 
     label = new JLabel(WAITING_FOR_CLICK); 
     add(label); 
    } 

    public void setButtonText() { 
     label.setText(JUST_CLICKED); 
     setBackground(CLICKED_COLOR); 

     new Timer(TIMER_DELAY, new ActionListener() { 
     public void actionPerformed(ActionEvent ae) { 
      label.setText(WAITING_FOR_CLICK); 
      setBackground(null); 
      ((Timer)ae.getSource()).stop(); 
     } 
     }).start(); 
    } 

} 

class MouseAdapterMod extends MouseAdapter { 

    // usually better off with mousePressed rather than clicked 
    public void mousePressed(MouseEvent e) { 
     ButtonPanel btnPanel = (ButtonPanel)e.getSource(); 
     btnPanel.setButtonText(); 
    } 
} 
+1

+1, 'getSource()' à la rescousse encore une fois lors de l'écriture d'un écouteur partagé. – camickr

+0

+1 bel exemple :-) – kleopatra

+0

Excellent exemple. Je reçois encore plus que ce que j'ai demandé. Mais je ne suis pas sûr de l'instance de 'Timer' dans la méthode' setButtonText() '. Désolé .. newbie in java;) .. Mais en tout cas, merci beaucoup! – Gubert