2011-09-07 23 views
6

Tôi có một lớp sự kiện whitch kéo dài JPanel:Xác định thành phần JPanel đã nhấp trong Trình ghi chuột. xử lý

public class ButtonPanel extends JPanel { 

    private label; 

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

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

} 

Tôi có một vài trường hợp mà lớp đó sẽ được thêm vào JFrame. Tôi muốn tạo một instanse của lớp MouseAdapter và sau đó thêm chúng như một người nghe chuột cho tất cả các thành phần ButtonPanel trên JFrame của tôi. Tôi quan tâm:

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

Lớp MouseAdapterMod Tôi muốn tách biệt với nhau và định vị trong gói riêng của nó. Nó nên trông như thế này:

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

Vì vậy, vấn đề là tôi không biết làm thế nào để thực hiện phương pháp mouseClicked để làm cho nó xác định của ButtonPanel tạo sự kiện này và gọi tương ứng với thành phần setButtonText() phương pháp. Có ai biết làm thế nào để làm điều đó?

Tôi biết rằng tôi có thể đạt được điều này bằng cách bao gồm chức năng xử lý sự kiện trong lớp ButtonPanel, nhưng đó không phải là cách phù hợp với tôi, vì tôi muốn giữ cấu trúc lớp như tôi đã mô tả ở trên và chỉ có một thể hiện của lớp MouseAdapterMod xử lý tất cả các ButtonPanels.

+0

Kudos cho đoạn cuối cùng của bạn. –

Trả lời

14

Phương pháp MouseEvent#getSource sẽ trở lại mà đối tượng đã được nhấp:

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

Theo các ý kiến ​​lưu ý, bạn thường tốt hơn hết nghe cho mousePressed hoặc mouseReleased hơn mouseClicked vì cho mouseClicked để làm việc, báo chí và phát hành phải từ cùng một điểm, và nếu con chuột chuyển ngay cả một số lượng nhỏ, nhấp chuột sẽ không đăng ký.

chương trình thử nghiệm của tôi:

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()' để giải cứu một lần nữa khi viết một người nghe được chia sẻ. – camickr

+0

+1 ví dụ hay :-) – kleopatra

+0

Ví dụ tuyệt vời. Tôi nhận được nhiều hơn tôi hỏi. Nhưng không chắc chắn thể hiện 'Timer' là gì trong phương thức' setButtonText() '. Xin lỗi .. newbie trong java;) .. Nhưng trong mọi trường hợp, cảm ơn bạn rất nhiều! – Gubert

Các vấn đề liên quan