2011-09-07 13 views
6

tengo una clase de sucesos générale extiende JPanel:Determine el componente de JPanel cliqueado en MouseListener. manipulación

public class ButtonPanel extends JPanel { 

    private label; 

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

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

} 

tengo varias instancias de esa clase que se añade a JFrame. Quiero crear un instanse de la clase MouseAdapter y luego agregarlos como un detector de mouse a todos los componentes de ButtonPanel en mi JFrame. Me 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 clase MouseAdapterMod Quiero ser separado del otro y localizar en su propio paquete. Debería ve así:

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 
    } 
} 

Así que el problema es que no sé cómo poner en práctica el método mouseClicked para que sea determinar cuál de ButtonPanel generar el evento y llamar a la correspondiente a ese componente setButtonText método(). ¿Alguien sabe cómo hacer eso?

Sé que puedo lograr esto incluyendo la funcionalidad de manejo de eventos en la clase ButtonPanel, pero no es la forma adecuada para mí, porque quiero mantener la estructura de clases como describí anteriormente y tener solo una instancia de la clase MouseAdapterMod para manejando todos los ButtonPanels.

+0

Felicitaciones por su último párrafo. –

Respuesta

14

El método MouseEvent#getSource devolverá el objeto que se ha hecho click:

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(); 
    } 
} 

Como la nota de los comentarios, es a menudo mejor escuchar a mousePressed o mouseReleased en lugar de mouseClicked porque para mouseClicked funcione, la prensa y la liberación debe ser desde el mismo punto, y si el mouse cambia incluso una pequeña cantidad, el clic no se registrará.

Mi programa de pruebas:

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()' al rescate una vez más al escribir un oyente compartido. – camickr

+0

+1 buen ejemplo :-) – kleopatra

+0

Excelente ejemplo. Recibo incluso más de lo que pedí. Pero no estoy seguro de qué es la instancia de 'Timer' en el método' setButtonText() '. Lo siento ... novato en Java;) .. Pero en cualquier caso, ¡muchas gracias! – Gubert

Cuestiones relacionadas