任何组件上都可以发生鼠标事件,如:鼠标进进组件、退出组件、在组件上方单击鼠标、拖动鼠标等都发生鼠标事件,也就是说,组件可以成为发生鼠标事件的事件源。
1 使用MouseListener接口处理鼠标事件
使用MouseListener接口可以处理5种操纵发生的鼠标事件:
(1)在事件源上按下鼠标键。mousePressed(MouseEvent )
(2)在事件源上开释鼠标键。mouseReleased(MouseEvent )
(3)在事件源上点击鼠标键。 mouseClicked(MouseEvent )
(4)鼠标进进事件源。 mouseEntered(MouseEvent )
(5)鼠标退失事件源。 mouseExit(MouseEvent )
鼠标事件的类型是MouseEvent,即当发生鼠标事件时,MouseEvent类自动创建一个事件对象。
MouseEvent类中有下列几个重要的方法:
(1)getX() 获取鼠标在事件源坐标系中的x坐标。
(2)getY() 获取鼠标在事件源坐标系中的y坐标。
(3)getModifiers() 获取鼠标的左键或右键。鼠标的左键和右键分别使用InputEvent类中的常量BUTTONl_MASK和BUTTON3_MASK来表示
(4)getClickCount() 获取鼠标被单击的次数。
(5)getSource() 获取发生鼠标事件的事件源。
事件源获得监视器的方法是addMouseListener(监视器)。
MouseListener接口中有如下方法:
(1)mousePressed(MouseEvent) 负责处理鼠标按下事件。即,当你在事件源按下鼠标时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
(2)mouseReleased(MouseEvent) 负责处理鼠标开释事件。即,当你在事件源开释鼠标时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
(3)mouseEntered(MouseEvent) 负责处理鼠标进进事件源事件。即,当鼠标进进时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
(4)mouseExited(MouseEvent) 负责处理鼠标离开事件。即,当鼠标离开容器时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
(5)mouseClicked(MouseEvent) 负责处理点击鼠标事件。即,当鼠标被单击时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
现在我们给出一个小程序mouse1.java,在这个小程序中有一个文本框,它负责记录鼠标事件。当鼠标进进小程序时,文本区显示甲鼠标进来了”;当鼠标离开时,文本区显示“鼠标走开了”;当鼠标被按下时,文本区显示“鼠标按下了”,并显示鼠标的坐标。
在下面例子mouse2.java中,当在画布上按下鼠标左键时,在鼠标位置处绘制一个圆;当按下鼠标右键时,在鼠标位置处绘制一个矩形:当鼠标退出画布时,清除绘制的全部图形。
下面的例子mouse3.java分别监视按钮、文本框和容器上的鼠标事件,当发生鼠标事件时,获取鼠标的坐标值,留意,事件源的坐标系的左上角是坐标源点
2 使用MouseMotionListener接口处理鼠标事件
使用MouseMotionListener接口可以处理两种操纵发生的鼠标事件:
(1)在事件源上拖动鼠标。
(2)在事件源上移动鼠标。
鼠标事件的类型是MouseEvent,即当发生鼠标事件时,MouseEvent类自动创建一个事件对象。 事件源获得监视器的方法是addMouseMotionListener(监视器)。
MouseMotionListener接口中有如下方法:
(1)mouseDragged(MouseEvent) 负责处理鼠标拖动事件。即,当你在事件源拖动鼠标时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
(2)mouseMoved(MouseEvent) 负责处理鼠标移动事件。即,当你在事件源移动鼠标时,监视器发现这个事件后将自动调用接口中的这个方法对事件作出处理。
在这里我们也提供一个非常简单的用鼠标作画的小程序mouse4.java。我们的想法很简单,只要我们能用鼠标画点,那么就可以用鼠标自由作画了。我们已经会用drawLine(int x1,int yl,int x2,int y2)画从点(x1,y1)到点(x2,y2)的直线,那么当直线的出发点和终点相同时,就画出了一个点。
现在让我们来分析一下例子4的代码。当我们拖动鼠标时(按着鼠标左键),我们就获得了鼠标拖动时的坐标,同时调用repaint()方法画下这个坐标点。我们已经知道,在小程序中调用repaint方法时,程序首先清除paint()方法以前所画的内容,然后再调用paint()方法。但有时我们不想让程序清除paint()方法以前所画的所有内容。实际上当我们调用
repaint()方法时,程序自动地调用update(Graphics g)方法(从父类Component继续下来的)清除paint()方法以前所画的内容,然后再调用paint方法。因此我们可以在我们的小程序中重写这个update(Graphics g)方法(即隐躲父类的方法),根据需要来清除哪些部分或保存哪些部分。在这个例子中,我们在updatte(Graphics g)方法体内没有清除以前所画的内容(假如预备清除可使用clearrect方法,见17.4节)而是继续调用paint方法。受上面例子的启发,你可能已经想到,我们可以通过画实心圆来改变线条的粗细。下面是一个略微复杂的例子mouse5.java。在这个例子中我们可以控制线条的颜色,而且我们还可以使用橡皮擦掉所画的图形。稍加改进就可以控制线条的粗细,另外还可以使用上一节先容的方法控制鼠标的外形。
3 鼠标事件的转移
假如我们正监视一个容器上的鼠标事件,而容器中添加了一些组件,则当在组件上进行单击鼠标、移动鼠标等操纵时,容器将不知道这些操纵的发生。
可以使用鼠标事件的转移将一个事件源发生的鼠标事件转移到另一个事件源上,也就是说,当用户的在某个事件源上单击鼠标时,可以通过鼠标事件的转移导致另一个事件源上发生鼠标事件(声东击西)。使用javax.swing包中的SwingUtilities类的静态方法:
MouseEvent convertMouseEvent(Component source,MouseEvent sourceEvent,Component destination)
可以将source组件上发生的鼠标事件转移到组件destination,该方法返回转移后的鼠标事件。 在下面的例子mouse6.java中,用户单击一个按钮,然后拖动鼠标移动按钮的位置,观察鼠标事件的转移。