在完成远程控制的客户端控制时
需要把客户端在界面上的鼠标事件记录下来
发送给被控端执行
那么这个鼠标监听器到底应该怎么加呢?
我们发现一个界面可以加的鼠标监听器有如下3个
testJFrame.addMouseListener(new MouseListener(){}); testJFrame.addMouseMotionListener(new MouseMotionListener(){}); testJFrame.addMouseWheelListener(new MouseWheelListener(){});
用内部类实现实现每个接口,都必须要重写每个接口中定义的所有抽象方法
但,并不是每个接口中的每个抽象方法所处理的鼠标事件都是我们需要的
比如
testJFrame.addMouseListener(new MouseListener(){ @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { } @Override public void mouseReleased(MouseEvent e) { } });
MouseListener中需要重写的抽象方法就多大5个,而其中我们真正需要的却只有mousePressed和mouseReleased
如果把所以抽象方法都复写,无疑是浪费自己的力气和页面
于是很简单的就想到了用MouseAdapter来复写我们需要需要的抽象方法
查看MouseAdapter API发现
public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener
这也是一个实现了3个鼠标监听器的抽象类
于是我们可以通过继承该类来重写所有我们需要的事件处理方法,而不用理会我们用不到的那几种,代码简单,明晰
新建MouseEventLisenter来处理需要处理的所有鼠标事件
public class MouseEventHandle extends MouseAdapter{ Client _client; public MouseEventHandle(Client client){ _client=client; } @Override public void mousePressed(MouseEvent e) { System.out.println("监听到鼠标按下"); int buttons = e.getButton(); _client.mousePressAct(buttons); } @Override public void mouseReleased(MouseEvent e) { System.out.println("监听到鼠标松开"); int buttons = e.getButton(); _client.mouseReleaseAct(buttons); } @Override public void mouseWheelMoved(MouseWheelEvent e) { int wheelRotation=e.getWheelRotation(); _client.mouseWheelAct(wheelRotation); } @Override public void mouseMoved(MouseEvent e) { int x = e.getX(); int y = e.getY(); _client.mouseMoveAct(x, y); } }
在界面上只要加上该类的一个实例化对象即可
终于,终于的终于,终于,废话说完了。
下面开始说明我们遇到的问题
在界面上用
//实例化鼠标事件监听器 ouseEventHandle mouseHandle=new MouseEventHandle(_client); // 给界面加鼠标监听器 erverSreenLabel.addMouseMotionListener(mouseHandle);
然后我们神奇的发现,鼠标move的时候能监听到,但是鼠标press和release时却怎么都监听不到
这怎么回事呢?
也太神奇了吧,折腾了半天,就是没发现问题
恍惚一会
想起,鼠标事件的监听,不还是事件监听器模型吗?
那么事件监听器模型的本质是什么呢?
用个简单的例子来对比说明一下
类A为事件生产者,每当A中的C执行后,我们就认为事件被生产
接口B为事件监听器接口,监听A中的C,也就是说,每当A中的C执行一次后,我们就执行B中对应的方法Handl
e来进行相应的事件处理
那么我们该怎么实现用B来监听A中的C呢?
这就要把B加入监听C的队列cListener中
听起来好像玄乎其玄,有点搞不明白,咱还是看代码吧
public class A { private java.util.ArrayList<B> cListener=new java.util.ArrayList<B>();//C的监听器队列 /** * 加监听器的方法 * @param b 监听器对象 */ public void addCListener(B b){ cListener.add(b); } public void c(){ } public void example(){ //……………… //……………… c(); fireHandle(); //每当监听到C,则执行处理方法 //………………………… } /** * 事件处理 */ private void fireHandle() { for(int i=0;i<cListener.size();i++){ cListener.get(i).handle(); } } }
/** * 事件c的监听器 * @author mzd * */ public interface B { public void handle() ;//事件处理方法 }
那么这个监听器该怎么用呢?
我们先用类D,实现接口B,在D中的handle()方法中重写我们需要的事件处理方法
然后把D加给A
从此,每当A中的C产生一次,D中的handle()方法就会执行,从而完成对A中C的监听
看代码
D的实现
public class D implements B{ @Override public void handle() { System.out.println("监听到A中C"); } }
public class Test { public static void main(String[] args) { A a=new A(); D d=new D(); a.addCListener(d); } }
好了
监听器模型回顾完了
还是回到我们遇到的问题
为什么我们明明用了
鼠标的press和release却没有被监听到呢?
我想,答案已经很明显了吧
因为我们只加了MouseMotionListener,所以,每次对应的MouseEvent执行后,fireMouseEvent方法只是从motionListener队列中调用相应的mouseMoved()方法
而鼠标点击和松开时,因为没有调用addMouseListener(),mouseListener队列为空,当中并没有我们自己实现的MouseEventHandle对象,所以每次执行时,也就自然没有执行到当中相应的mousePressed()和mouseReleased()方法
改正的方法很简单
把我们自己实例化的MouseEventHandle给3个监听器队列都加上就OK了
代码如下