8.9.2组件重绘的处理
组件重绘的原理:组件在大小改变或隐藏后又显示,AWT线程都会重新绘制组件,组件上原来的图形就不复存在了。
Paint(Grahpics g)的作用:使用Grahpic对象,对图形进行重新绘制
编程举例:在窗口上画直线和打印文本的功能,并在窗口重绘后重绘窗口上的所有直线。
DrawLine.java中:
package myprojects.drawline;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class DrawLine extends Frame{
int orgX;
int orgY;
int endX;
int endY;
Vector vLines = new Vector();
public void paint(Graphics g)//必须保存下线条的所有信息
{
//实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。连续调用 nextElement
方法将返回一系列的连续元素。
//hasMoreElements()测试此枚举是否包含更多的元素
Enumeration e = vLines.elements();
while(e.hasMoreElements())
{
MyLine line =(MyLine)e.nextElement();
line.drawMe(g);
//g.drawLine(orgX,orgY,endX,endY);
}
}
public DrawLine(){
addWindowListener(new WindowAdapter(){
public void windowClosing (WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e)
{
endX = e.getX();
endY = e.getY();
Graphics g = getGraphics();
/*g.setColor(Color.RED);//设置绘图颜色为红色
g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));//设置文本的字体
g.drawString(orgX +"," +orgY,orgX,orgY);//打印鼠标按下时的坐标文本
g.drawString(e.getX()+","+e.getY(),e.getX(),e.getY());//打印鼠标释放时的坐标文本
g.drawLine(orgX,orgY,e.getX(),e.getY());*/
vLines.add(new MyLine(orgX,orgY,endX,endY));
repaint();
}
}
);
}
public static void main(String [] args)
{
System.out.println("Starting DrawLine");
DrawLine mainframe = new DrawLine();
mainframe.setSize(400,400);
mainframe.setTitle("DrawLine");
mainframe.setVisible(true);
}
}
MyLine中代码:
package myprojects.drawline;
import java.awt.Graphics;
class MyLine {
private int orgX;
private int orgY;
private int endX;
private int endY;
public MyLine(int orgX,int orgY,int endX,int endY)
{
this.orgX = orgX;
this.orgY = orgY;
this.endX = endX;
this.endY = endY;
}
public void drawMe(Graphics g)
{
g.drawLine(orgX,orgY,endX,endY);
}
}
8.9.3图像显示
使用Graphics.drawlmage(Image img,int x,int y,ImageObserver observer)方法显示图像
使用Component.getToolkit.getImage(String path)语句获得Image实例对象
drawImage是一个异步方法,即便img对应的图像还没有完全装载,也会立即返回;Image是抽象类,不能使用构造方法,只能通过某个方法来产生一个Image对象,猜想是getImage或createImage之类,再通过查询JDK帮助文档解决问题;
文档中说得非常清楚,只有组件已显示在窗口上时,getGraphics方法才能正确返回一个Graphics对象。
放在Frame.setVisible(true)之后的GUI程序代码,在窗口初始显示时,都看不到期望的执行效果;
import java.awt.*;
import java.awt.event.*;
public class DrawImage extends Frame{
Image img = getToolkit().getImage("..\\logo.gif");
public void paint(Graphics g)
{
g.drawImage(img,0,0,this);//paint方法会擦除窗口上绘制的图像,重绘代码放在此方法中可以实现重绘效果;
}
public DrawImage(){
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
}
public static void main(String[] args) {
System.out.println("Starting DrawImage...");
DrawImage mainFrame = new DrawImage();
mainFrame.setSize(400,400);
mainFrame.setTitle("DrawImage");
mainFrame.setVisible(true);
/*Graphics g = mainFrame.getGrahpics();
while(!g.mainFrame.getGraphics().drawImage(img,0,0,mainFrame));*/
}
}
8.9.4双缓冲技术
调用Component.createImage方法创建内存Image对象;
在Image对象上进行绘制的结果就成了一幅图像
在Image对象上执行与组件表面同样的绘制,Image对象中的图像是组件表面内容的复制,当组件重画时,只需将内存中的Image对象在组件上画出
编程实例:使用双缓冲区技术重绘组件表面的所有图形。
package myprojects.drawline;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
class DrawLine1 extends Frame{
int orgX;
int orgY;
int endX;
int endY;
Image oimg = null;
Graphics og = null;
Vector vLines = new Vector();
public void paint(Graphics g)
{
if(oimg!=null)
{
g.drawImage(oimg,0,0,this);
}
}
public DrawLine1(){
setSize(400,400);
setTitle("DrawLine");
setVisible(true);//只有部件显示在了桌面上后才能调用createImage方法
Dimension d = getSize();
oimg = createImage(d.width,d.height);
og = oimg.getGraphics();
addWindowListener(new WindowAdapter(){
public void windowClosing (WindowEvent e){
dispose();
System.exit(0);
}
});
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
orgX = e.getX();
orgY = e.getY();
}
public void mouseReleased(MouseEvent e)
{
endX = e.getX();
endY = e.getY();
Graphics g = getGraphics();
g.setColor(Color.RED);//设置绘图颜色为红色
g.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));//设置文本的字体
g.drawString(orgX +"," +orgY,orgX,orgY);//打印鼠标按下时的坐标文本
g.drawString(e.getX()+","+e.getY(),e.getX(),e.getY()); //打印鼠标释放时的坐标文本
g.drawLine(orgX,orgY,e.getX(),e.getY());
og.setColor(Color.RED);//设置绘图颜色为红色
og.setFont(new Font(null,Font.ITALIC|Font.BOLD,30));//设置文本的字体
og.drawString(orgX +"," +orgY,orgX,orgY);//打印鼠标按下时的坐标文本
og.drawString(e.getX()+","+e.getY(),e.getX(),e.getY());
og.drawLine(orgX,orgY,e.getX(),e.getY());
}
}
);
}
public static void main(String [] args)
{
System.out.println("Starting DrawLine");
DrawLine1 mainframe = new DrawLine1();
}
}