确定MouseListener中单击的JPanel组件。事件处理 [英] Determine clicked JPanel component in the MouseListener. Event handling

查看:133
本文介绍了确定MouseListener中单击的JPanel组件。事件处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类whitch扩展JPanel:

I have a class whitch extends 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组件。我是:

I have several instances of that class which is added to JFrame. I want to create one instanse of MouseAdapter class and then add them as a mouse listener to all of the ButtonPanel components on my 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);

MouseAdapterMod类我希望与另一个分开并找到它自己的包中。它应该如下所示:

The MouseAdapterMod class I want to be separate from the other and locate in it's own package. It should looks like this:

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()方法。有谁知道怎么做?

So the problem is that I don't know how to implement mouseClicked method to make it determine which of ButtonPanel generate the event and call the corresponding to that component setButtonText() method. Is anyone know how to do that?

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

I know that I can achieve this by including event handling functionality in the ButtonPanel class, but thats not appropriate way for me, cuz I want to keep the class structure as I described above and have only one instance of MouseAdapterMod class for handling all of the ButtonPanels.

推荐答案

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

The MouseEvent#getSource method will return which object has been clicked:

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,因为要鼠标点击工作,按下和释放必须来自同一点,如果鼠标移动了一点点,点击将不会注册。

As the comments note, you're often better off listening for mousePressed or mouseReleased rather than mouseClicked because for mouseClicked to work, the press and release must be from the same point, and if the mouse shifts even a slight amount, the click won't register.

我的测试程序:

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

这篇关于确定MouseListener中单击的JPanel组件。事件处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆