确定MouseListener中单击的JPanel组件。 事件处理

我有一个类whitch扩展JPanel:

public class ButtonPanel extends JPanel { private label; public ButtonPanel() { label=new JLabel("waiting for click"); add(label); } public void setButtonText() { label.setText("just clicked"); } } 

我有几个类的实例添加到JFrame。 我想创建一个MouseAdapter类的instanse,然后将它们作为鼠标监听器添加到我的JFrame上的所有ButtonPanel组件。 我看:

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

MouseAdapterMod类我希望与另一个分开,并找到它自己的包。 它应该是这样的:

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

所以问题是我不知道如何实现mouseClicked方法来确定哪个ButtonPanel生成事件并调用对应的那个组件setButtonText()方法。 有谁知道怎么做?

我知道我可以通过在ButtonPanel类中包含事件处理function来实现这一点,但这对我来说不合适,因为我想保留上面描述的类结构并且只有一个MouseAdapterMod类实例来处理所有的ButtonPanels。

MouseEvent#getSource方法将返回单击的对象:

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

正如评论所指出的那样,你通常最好不要使用mousePressed或mouseReleased而不是mouseClicked,因为要使mouseClicked工作,按下和释放必须来自同一点,如果鼠标移动了一小部分,则点击赢了注册。

我的测试程序:

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