2011-09-07 8 views
6

Mam klasy Event whitch rozszerza JPanel:Określa kliknięcie komponentu JPanel w narzędziu MouseListener. obsługi

public class ButtonPanel extends JPanel { 

    private label; 

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

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

} 

Mam kilka wystąpień tej klasy, która jest dodawana do JFrame. Chcę utworzyć jedną instancję klasy MouseAdapter, a następnie dodać ją jako detektor myszy do wszystkich składników ButtonPanel w mojej ramce JFrame. I 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); 

Klasa MouseAdapterMod Chcę być oddzielone od innych i zlokalizować w jego własnym opakowaniu. powinno to wyglądać tak:

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

Tak więc problem jest to, że nie wiem jak zaimplementować metodę mouseClicked, aby określić, które z ButtonPanel generowania zdarzenia i wywołać odpowiedni do tego składnika setButtonText metoda(). Czy ktoś wie, jak to zrobić?

Wiem, że mogę to osiągnąć przez włączenie funkcji obsługi zdarzeń w klasie ButtonPanel, ale to nie jest odpowiedni sposób dla mnie, ponieważ chcę zachować strukturę klas, jak opisano powyżej i mam tylko jedno wystąpienie klasy MouseAdapterMod dla obsługa wszystkich ButtonPaneli.

+0

Kudos do ostatniego akapitu. –

Odpowiedz

14

Sposób MouseEvent#getSource powróci który obiekt został wciśnięty:

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

W nocie komentarze, jesteś często lepiej nasłuchując mousePressed lub mouseReleased zamiast mouseClicked bo mouseClicked do pracy, prasę i zwolnienie musi pochodzić z tego samego punktu, a jeśli mysz przesunie się nawet nieznacznie, kliknięcie nie zostanie zarejestrowane.

Mój program testowy:

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()' na ratunek jeszcze raz podczas pisania współdzielonego obiektu nasłuchującego. – camickr

+0

+1 ładny przykład :-) – kleopatra

+0

Doskonały przykład. Dostaję jeszcze więcej, niż prosiłem. Ale nie jestem pewien, co to jest instancja 'Timer' w metodzie' setButtonText() '. Przepraszamy .. newbie w java;) .. Ale w każdym razie, dziękuję bardzo! – Gubert