程序概述
在示例中,提供了 mousePressed 和 mouseClicked 方法。当鼠标点击在所有小方块的像素之外时,就会绘制一个新的小方块。这个操作在 mousePressed 方法中实现的,这样可以让用户的操作立即得到相应,而不必等到释放鼠标按键。如果用户在某个小方块中双击鼠标,就会将它擦除。由于需要知道点击的次数,这个操作在mouseClick中实现。
mouse/MouseFrame.java
程序的主类
package mouse;
import javax.swing.*;
public class MouseFrame extends JFrame{
private static final long serialVersionUID = 1L;
public static void main(String[] args){
MouseFrame mouseFrame = new MouseFrame();
mouseFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mouseFrame.setVisible(true);
}
public MouseFrame() {
add(new MouseComponent());
pack();
}
}
mouse/MouseComponent.java
package mouse;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class MouseComponent extends JComponent{
private static final long serialVersionUID = 1L;
private static final int SIZELENGTH = 10; //小方块的边长
private ArrayList<Rectangle2D> squares; // 存储小方块的坐标的动态数组,数组中每个元素是一个矩形对象
private Rectangle2D current; //当前小方块
public MouseComponent(){
squares = new ArrayList<>();
current = null;
addMouseListener(new MouseHandler());
addMouseMotionListener(new MouseMotionHandler());
}
//画小方块
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 - SIZELENGTH / 2, y - SIZELENGTH / 2, SIZELENGTH, SIZELENGTH);
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);
}
}
/**
* 鼠标移动事件接口
*/
public 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 - SIZELENGTH / 2, y - SIZELENGTH / 2, SIZELENGTH, SIZELENGTH);
repaint();
}
}
}
//返回一个窗口的大小用于程序的首选窗口
private static final int DEFAULT_WIDTH = 700;
private static final int DEFAULT_HEIGHT = 500;
public Dimension getPreferredSize() {
return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
}
}
- 学习《Java核心技术卷一》之事件处理