Java 绘图技术
Java 绘图入门
就像绘画一样,需要画板画笔才能绘画,画完再装入画框,Java 也有一套类似的机制
- 定义画板类 继承 JPanel
- 重写绘图方法 paint,方法体的第一行语句需要调用父类 paint 方法完成初始化
- 自定义测试类继承 JFrame 画框
- 完善构造函数,完成设置
代码:
// 3. 自定义测试类继承 JFrame 画框
public class CircleTest extends JFrame { // JFrame 对应窗口,可以理解成画框
// 定义面板
private MyPanel mp = null;
public static void main(String[] args) {
new CircleTest();
}
// 4. 完善构造函数,完成设置
public CircleTest() {
// 初始化面板
mp = new MyPanel();
// 把面板放入到窗口(画框)
this.add(mp);
// 设置窗口大小
this.setSize(400, 300);
this.setVisible(true); // 可视化
}
}
// 1. 定义画板类 继承 JPanel
class MyPanel extends JPanel {
// Graphics 类似一个画笔,MyPanel 对象类似画板
// Graphics
// 2. 重写绘图方法 paint,方法体的第一行语句需要调用父类 paint 方法完成初始化
@Override
public void paint(Graphics g) { // 绘图方法
super.paint(g); // 调用父类方法完成初始化
// 画圆
g.drawOval(10,10, 100, 100);
}
}
绘图原理
component 类提供了两个和绘图相关的重要方法:
- paint(Graphics g) 绘制组件的外观
- repaint() 刷新组件的外观
paint() 方法被调用的时机:
- 组件第一次在屏幕显示
- 窗口最小化后再最大化
- 窗口的大小发生变化
- repaint() 方法被调用时
Java 事件处理机制
Java 事件处理是采取“委派事件模型”。
当事件发生时,产生事件的对象会把“信息”传递给事件的“监听者”。这里的信息是指事件类库中某个类对应的对象,也就是“事件的对象”
简单的说,就是对某个事件设置一个监听器,只要事件发生就触发监听器,进而就触发了某个对应方法,我们想要的就是在事件发生时触发方法。就像 FBI 监视某个人(监听器),只要他一出门(事件)就给通知领导(方法)
- 事件源:产生事件的对象,如按钮,鼠标,监视对象
- 事件:事件源的某个行为,或者状态。如按钮点击/松开,鼠标点击,监视对象出门
- 事件监听者:监听事件源是否发生事件,若发生则触发应对方法。如 键盘监听器监听按键,FBI 监视某个人
- 对应方法:事件发生后的对应方法
键盘监听器 KeyListener
在上一部分的画板部分中,创建画板的监听器时实现 KeyListener 接口,然后重写键盘监听器的方法:
- keyTyped() 有字符输出时,触发该方法
- keyPressed() 监听某个键位按下
- keyReleased() 监听某个键位松开
使用步骤为:
- 画板类实现 KeyListener 接口,重写对应的监听方法
- 在画框类的构造器中添加键盘监听器
小球移动案例展示:
/**
* 演示小球通过键盘控制上下左右移动
* 讲解Java事件控制
*/
public class BallMove extends JFrame {
BallPanel bp;
public static void main(String[] args) {
new BallMove();
}
public BallMove() {
bp = new BallPanel();
this.add(bp);
this.setSize(400, 400);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
// 2. 在画框类的构造器中添加键盘监听器
this.addKeyListener(bp);
}
}
/**
* 画一个小球,并且可以通过鼠标移动
* KeyListener 是键盘监听器
* 1. 画板类实现 KeyListener 接口,重写对应的监听方法
*/
class BallPanel extends JPanel implements KeyListener {
// 设置小球坐标
int x = 10;
int y = 10;
@Override
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 30, 30);
}
// 有字符输出时,触发该方法
@Override
public void keyTyped(KeyEvent e) {
}
// 监听某个键位按下
@Override
public void keyPressed(KeyEvent e) {
// 根据用户输入,控制小球移动
// Java 会给每一个键设置一个对应码
// KeyEvent.VK_DOWN 指 向下方向键
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
y++;
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
x++;
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
y--;
} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
x--;
}
// 让面板重绘
this.repaint();
}
// 监听某个键位松开
@Override
public void keyReleased(KeyEvent e) {
}
}