Double buffer technology and Canvas, JPanel

Double buffer technology and Canvas, JPanel

I just learned java. I recently wrote a small sketchpad program in java, using double buffer technology. The first time I write, I might have some dishes, everyone will take a look.

This time I write a blog to better understand and remember myself. Let me talk a little bit of nonsense and understand the double cache technology.

In the java program related to drawing and picture dynamic operation, the repaint() method cannot be redrawn. The process of redrawing is essentially a process of continuous scraping and redrawing. But it takes a certain amount of time to complete this series of operations on the screen, and the more complex the graphics on the screen, the longer it will take. The white-scratching-redrawing operation that we can see with the naked eye will make us intuitively feel The screen flickers.

To solve the flicker problem, it is essentially to solve the whitening-redrawing process that we can perceive with the naked eye, so the double buffer technology is introduced. The core of the double-buffer technology is to open up a "logical screen" in the memory that is as large as the current screen. Our drawing and animation operations all act on this "logical screen" first. When an operation is completed on this "logical screen", then the entire "logical screen" is put on our screen. In this case, we You can't see the redrawing process of the entire graph on the screen, thus solving the flicker problem. Just like watching anime, without double buffering technology, just draw one frame and watch one frame, it will definitely freeze. With the double buffer technology, each frame will be drawn in advance and will be flipped to show you.
First define two private variables in the class, these two private variables, these two private variables will act as "logic screen" and "logic pen" in the subsequent code,

private java.awt.Image iBuffer;
private Graphics2D gBuffer;

Dimension encapsulates the length and width of the container that calls it. Through this class, the length and width of the current display screen can be obtained to facilitate the definition of logical screens. It should be noted here that the graphics drawn by gBuffer will not appear on the screen immediately. The graphics drawn by it are only for the logic drawing board.

public void paint(Graphics g) {
         Dimension size = getSize();
	      int width = size.width;
	      int height = size.height;
	      
	      if(iBuffer==null)
	      {
	         iBuffer=createImage(width,height);//创建一块和显示屏幕等大的“逻辑屏幕”。
	         gBuffer=(Graphics2D)iBuffer.getGraphics();//用“逻辑屏幕”的getGraphics操作创建并返回“逻辑画笔”。
	      }
	      
	      gBuffer.setColor(Color.WHITE);
	      gBuffer.fillRect(0,0,width,height);//这两步操作,将“逻辑画板”刮白
	      
	      
	      abstract_shape shape=null;
	      myiterator list=save.create_iterator();
	      while(list.isnext()) {
	    	  shape=list.next();
	    	  shape.paint(gBuffer);
	      }//这两步操作,是通过之前就保存好的绘图信息。将之前的画图内容重现。也就是重绘
	      
	   ....................
	   ....................
	   ...................//这里省略的操作,应该是用 gBuffer画笔,在“逻辑画板”上绘制当前想要画的图形。
	   
          g.drawImage(iBuffer,0,0,this);//这一步操作,将“逻辑画板”上的内容整个投射到屏幕上,让我们可以看见。
	  }

Under such operating conditions, the redrawing process is not visible, which solves the screen flicker. What needs special attention here is that g and gBuffer are both brush classes, but they target different objects. The pen type g is aimed at the screen, and the graph drawn with g is directly displayed on the screen. When the double buffer technology is not used, g is used for drawing directly. gBuffer acts on iBuffer, which is the "logic drawing board".

After talking about double caching, let me discuss the problems that occurred in the process of writing this drawing board. As a beginner, the problem may be very low-level, I hope you guys will testify.

public class draw extends Canvas implements MouseListener, MouseMotionListener

In the beginning, my custom artboard class inherited the Canvas canvas class. According to the query data, the repaint method will determine the magnitude of the component, the heavyweight calls the update() method, and the light weight directly calls the paint() method. Canvas is a heavyweight component, so I want to write the double cache technology in the update() method to facilitate code maintenance. After rewriting update() and running, it still flickers. It was found that the update() method was not called during the test, and the search for the data was fruitless. So the solution in front of me is to rewrite reapint() or write the double-buffer technology into paint(), considering its own technical problems, choose the second one.

After the double buffer was written, it was still flickering, but it was a different method. Without double buffering, each graphic flashes in sequence. After using the double buffer, the entire drawing board flickered, and the search for information failed. So I tried to change Canvas to JPanel.

public class draw extends JPanel implements MouseListener, MouseMotionListener

At this point, the flickering problem that plagued me for a day was solved, but two questions that I could not get the answer to were raised.

1. Why do I inherit the Canvas class, when I call the repaint() method, the update() method is not called. Is it because of inheritance?
2. What is the difference between Canvas class and JPanel class. I know that Canvas is a heavyweight component, and JPanel is a lightweight component. Does it have anything to do with this?

As a beginner, I hope you guys can advise.

Guess you like

Origin blog.csdn.net/weixin_43797829/article/details/106530283