当点击鼠标按钮时,有三个监听器方法可以调用:①鼠标按下时调用mousePressed;②鼠标被释放时调用mouseReleased;③关注鼠标的最终点击事件时调用mouseClicked。鼠标点击可以由mouseClicked过程报告,该方法是MouseListener接口的一部分。通常大部分应用程序只对鼠标点击事件感兴趣,而对鼠标移动及拖动并不感兴趣,但是鼠标移动及拖动事件又经常发生,因此,鼠标移动与拖动事件定义在一个MouseMotionListener接口中。
因为MouseListener接口中有很多方法,而其中很多并不一定是我们需要的,但是我们在实现该接口的类时又必须实现MouseListener接口中所有的方法。庆幸的是,MouseAdapter类实现了MouseListener接口中的所有方法(就是空方法,并没有编写方法的具体执行过程),我们可以直接继承该类并重写我们需要的方法就可以了。下面的示例程序通过分别定义两个类MouseHandler和MouseMotionHandler演示了鼠标的点击监听、鼠标移动和拖动事件监听:
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class MouseDemo {
public static void main(String[] args){
EventQueue.invokeLater(() -> {
JFrame frame = new MouseFrame();
frame.setTitle("MouseTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class MouseFrame extends JFrame{
public MouseFrame(){
add(new MouseComponent());
pack();
}
}
class MouseComponent extends JComponent{
private static final int DEFAULT_WIDTH = 300;
private static final int DEFAULT_HEIGHT = 200;
private static final int SIDELENGTH = 10;
private ArrayList<Rectangle2D> squares;
private Rectangle2D current; // the square containing the mouse cursor
public MouseComponent(){
squares = new ArrayList<>();
current = null;
addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
}
public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
for (Rectangle2D r : squares)
g2.draw(r);
}
public Rectangle2D find(Point2D p){
for (Rectangle2D r : squares){
if (r.contains(p)) return r;
}
return null;
}
public void add(Point2D p){
double x = p.getX();
double y = p.getY();
current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
squares.add(current);
repaint();
}
public void remove(Rectangle2D s){
if (s == null) return;
if (s == current) current = null;
squares.remove(s);
repaint();
}
private class MouseHandler extends MouseAdapter{
public void mousePressed(MouseEvent event){ //鼠标按下时调用
current = find(event.getPoint());
if (current == null) add(event.getPoint());
}
public void mouseClicked(MouseEvent event){ //鼠标点击时调用,点击两次则移除矩形
current = find(event.getPoint());
if (current != null && event.getClickCount() >= 2) remove(current);
}
}
private class MouseMotionHandler implements MouseMotionListener{
public void mouseMoved(MouseEvent event){ //鼠标移动时调用
if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
}
public void mouseDragged(MouseEvent event){ //鼠标按住拖动时调用
if (current != null){
int x = event.getX();
int y = event.getY();
current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
repaint();
}
}
}
}