图形为什么会消失
简易画图板上当改变界面大小(最大化、最小化)时,画板上绘制的图形会全部消失,这是为什么呢?原因是这样的:
图形界面时由容器组件和元素组件构成的,而所有的组件都是采用的C和C++的代码,AWT组件就是通过调用操作系统底层的绘图函数来实现的;SWING组件则是在AWT组件的基础上,采用纯Java语言实现的。
重绘定义
在画图工具中,因为画布是在顶级容器中画出来的,而顶级容器(所有的组件)也都是由系统画出来的,在改变窗体大小时,组件会自动重新绘制,而我们画的图形则会消失绘制。这时为了使我们的图形在改变窗体时也不消失,就需要用到重绘;
我们所绘制图形的数据都存储在内存中,在创建窗体时我们已经定义了窗体的大小,如果我们再次改变窗体大小的时候,原来的窗体就不满足显示的需求。这时候就会自动调用组件的绘制方法,将窗体上所有的组件再重新绘制一次,但是不会执行我们所绘制的图形的代码,所以我们看到的就是绘图板界面还在,但是界面上之前绘制的图形消失了。操作系统重绘窗体上的组件时,调用了paint方法,这个方法是定义在JFrame和JPanel中都有的,叫做
Public void paint (Graphics g) { }
想要改变这个方法,就必须定义一个类继承组件,然后才能重写paint方法。最重要的一点就是,该类必须继承JFrame类或是JPanel类,不然不可以重写paint方法
创建NowImagePixel来储存图像中每个像素点的位置和RGB
public class NowImagePixel {
int x;
int y;
int pixelRGB;
public NowImagePixel( int x, int y,int pixelRGB) {
this.pixelRGB = pixelRGB;
this.x = x;
this.y = y;
}
}
首先创建MyPanel类继承JPanel来完成后续重绘工作
public class MyPanel extends JPanel{
static final int weight = Pixel.weight;
static final int height = Pixel.height;
NowImagePixel[][]nowImagePixel;
//上面的数组作用是接收图像数据
public void paint(Graphics g) {
super.paint(g);
//首先要调用父类paint方法
if(nowImagePixel!=null) {
int width=0;
int height=0;
for(int i=0;nowImagePixel[0][i]!=null;i++)width++;
for(int i=0;nowImagePixel[i][0]!=null;i++)height++;
if(width==0||height==0)return ;
/*因为我在监听器的类中创建的nowImagePixel二维数组大小
为我的显示屏分辨率,所以需要重新计算图像的宽和高*/
BufferedImage tempBufferedImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
for(int i=0;i<height;i++) {
for(int j=0;j<width;j++) {
tempBufferedImage.setRGB(j,i,nowImagePixel[i][j].pixelRGB);
}
}
g.drawImage(tempBufferedImage,0,0,null);
}
}
}
在PixelMouse类中创建nowImagePixel 二维数组用来保存图像数据
NowImagePixel[][] nowImagePixel = new NowImagePixel[1080][1920];
然后在PixelMouse中的pixelShow方法中向nowImagePixel中读入数据
public void pixelShow(BufferedImage bufferedImage,int[][]pixelArr) {
if(nowImagePixel[0][0]!=null)deleteNowImagePixel(nowImagePixel);
//deleteNowImagePixel方法是用来将上一个图像的数据清清除的方法,方法定义如下
/*public void deleteNowImagePixel(NowImagePixel[][]nowImagePixel) {
for(int i=0;i<nowImagePixel.length;i++) {
for(int j=0;j<nowImagePixel[0].length;j++) {
nowImagePixel[i][j]=null;
}
}
}*/
for(int i=0;i<pixelArr.length;i++) {
for(int j=0;j<pixelArr[0].length;j++) {
nowImagePixel[i][j]=new NowImagePixel(j,i,pixelArr[i][j]);
bufferedImage.setRGB(j,i,pixelArr[i][j]);
}
}
g.drawImage(bufferedImage,0,0,null);
}
然后在initUI主方法中创建MyPanel对象,再将PixelMouse中的nowImagePixel数组中的数据传递到
MyPanel对象中,最终完成重绘
MyPanel jp = new MyPanel();
PixelMouse mouse = new PixelMouse();
jp.nowImagePixel = mouse.nowImagePixel;
效果图
放大之后依然存在