AWT 图形图像处理
概述
- Java 图形图像程序设计经常涉及一个方法(paint)和两个对象(Canvas 和 Graphics)。“paint(Graphics g)”是 Component 的一个方法,负责接收系统发送的刷新消息;而 Graphics 能进行图形、文本、图像的绘制,Graphics 对象不由用户创建,只能由系统发送 paint 消息时自动传入;Canvas 是 Component 的一个子类,代表屏幕上的一块空白的矩形区域,程序能够在这个组件表面绘图。同 Container 相比,Canvas 是一个低级用户界面,因为它在构成界面时,没有 Container 来得容易,但可以进行一些更加灵活的操作。
设计能进行图形图像绘制的程序,需要自定义一个继承 Canvas 的类,并在类中覆盖 paint 方法。
组件重绘
组件的绘制需要调用 paint 方法。根据调用来源的不同,可分为两种情况:
(1)AWT 线程自动调用:当组件最小化后重新显示时;当组件被其他组件挡住后重新再现时;当组件拖动时,AWT 线程将自动调用组件的 paint 方法进行重新绘制。
(2)程序调用:调用 repaint 方法,通知 AWT 线程进行刷新。
Graphics 对象
- Graphics 对象由系统产生,程序只能引用而不能创建。要得到 Graphics 对象的引用,可采取下面两种方式:
(1)在 paint 方法当中,由其参数得到该对象的引用。
(2)调用 Component 的 getGraphics 方法得到该组件对象的 Graphics 引用。
import java.awt.*;
import java.awt.event.*;
public class GraphicImageDemo {
public static void main(String[] args) {
Frame f = new Frame("GraphicsText");
f.setBounds(100, 100, 230, 230);
Image img = f.getToolkit().getImage("earth.jpg");
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//f.getGraphics()一句一定要放到setVisible语句后,
//因为只有到这一句后,才建立了绘图对象
f.getGraphics().drawImage(img, 0, 0, f);
}
}
程序执行完毕后,并没有输出相应的图像,原因是 setVisible 后需要调用窗口的 paint 方法,而这个方法的调用是 AWT 线程管理的,比 f.getGraphics().drawImage(img, 0, 0, f) 代码滞后,所以图像输出后,“paint()”又将图像清空了。为了能让图像显现,需要将图像绘制代码写到 paint 方法中。
import java.awt.*;
import java.awt.event.*;
public class GraphicImageDemo extends Frame {
private Image img;
public void init() {
setBounds(100, 100, 230, 230);
img = getToolkit().getImage("earth.jpg");
setVisible(true);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
public void paint(Graphics g) {
if(img != null) {
g.drawImage(img, 40, 40, this);
}
}
public static void main(String[] args) {
GraphicImageDemo f = new GraphicImageDemo();
f.init();
}
}
双缓存技术
- 在 Component 及其子类的 paint 方法中进行图形图像绘制时,如果绘制内容复杂且频繁时,往往比较费时,常常出现绘制界面的抖动。为了解决这个问题,可以先将绘制的内容保留在一个 Image 对象当中,如果需要重新显示绘制的内容,例如界面最小化后重新浮现,仅仅简单地将这个 Image 内容再现就行了,这个技术就是双缓存技术。
import java.awt.*;
import java.awt.event.*;
class MyCanvas extends Canvas {
private Image img;
private Graphics og;
public void init() {
Dimension d = getSize();
img = createImage(d.width, d.height);
og = img.getGraphics();
og.setColor(Color.blue);
og.fillRect(30, 30, 60, 60);
og.setColor(Color.yellow);
og.fillOval(15, 15, 30, 30);
og.setXORMode(Color.red);
og.fillOval(75, 75, 30, 30);
og.setPaintMode();
og.setColor(Color.green);
og.fillArc(150, 40, 60, 60, 30, 160);
}
public void paint(Graphics g) {
if(img != null) {
g.drawImage(img, 20, 20, this);
}
}
}
public class DoubleBufferDemo {
public static void main(String[] args) {
Frame f = new Frame("DoubleBufferDemo");
f.setBounds(100, 100, 250, 200);
MyCanvas mc = new MyCanvas();
f.add(mc);
f.setVisible(true);
mc.init();
mc.repaint();
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}