Tecnología de doble búfer y Canvas, JPanel

Tecnología de doble búfer y Canvas, JPanel

Acabo de aprender Java. Recientemente escribí un pequeño programa de bloc de dibujo en Java, utilizando tecnología de doble búfer. La primera vez que escriba, puede que tenga algunos platos, todos echarán un vistazo.

Esta vez escribo un blog para entenderme mejor y recordarme a mí mismo, déjame decirte un poco de tonterías y entender la tecnología de doble caché.

En el programa java relacionado con el dibujo y la operación dinámica de imágenes, el método repaint () no se puede volver a dibujar. El proceso de volver a dibujar es esencialmente un proceso de raspado y redibujado continuo. Pero se necesita cierto tiempo para completar esta serie de operaciones en la pantalla, y cuanto más complejos sean los gráficos en la pantalla, más tiempo llevará. La operación de rayar y redibujar en blanco que podemos ver a simple vista nos hará sentir intuitivamente La pantalla parpadea.

Para solucionar el problema del parpadeo, se trata fundamentalmente de solucionar el proceso de blanqueamiento-redibujado que podemos percibir a simple vista, por lo que se introduce la tecnología de doble búfer. El núcleo de la tecnología de doble búfer es abrir una "pantalla lógica" en la memoria que es tan grande como la pantalla actual. Todas nuestras operaciones de dibujo y animación actúan primero en esta "pantalla lógica". Cuando se completa una operación en esta "pantalla lógica", la "pantalla lógica" completa se coloca en nuestra pantalla. En este caso, No puede ver el proceso de redibujo de todo el gráfico en la pantalla, resolviendo así el problema del parpadeo. Al igual que ver anime, sin tecnología de doble búfer, solo dibuja un fotograma y mira un fotograma, definitivamente se congelará. Con la tecnología de doble búfer, cada cuadro se dibujará de antemano y se volteará para mostrárselo.
Primero defina dos variables privadas en la clase, estas dos variables privadas, estas dos variables privadas actuarán como "pantalla lógica" y "lápiz lógico" en el código posterior,

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

Dimension encapsula el largo y ancho del contenedor que lo llama, a través de esta clase se puede obtener el largo y ancho de la pantalla de visualización actual para facilitar la definición de pantallas lógicas. Cabe señalar aquí que los gráficos dibujados por gBuffer no aparecerán en la pantalla inmediatamente, los gráficos dibujados por él son solo para el tablero de dibujo lógico.

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);//这一步操作,将“逻辑画板”上的内容整个投射到屏幕上,让我们可以看见。
	  }

En tales condiciones de funcionamiento, el proceso de redibujado no es visible, lo que resuelve el parpadeo de la pantalla. Lo que necesita atención especial aquí es que g y gBuffer son clases de pincel, pero apuntan a objetos diferentes. El lápiz tipo g apunta a la pantalla y el gráfico dibujado con g se muestra directamente en la pantalla. Cuando no se usa la tecnología de doble búfer, g se usa para dibujar directamente. gBuffer actúa sobre iBuffer, que es el "tablero de dibujo lógico".

Después de hablar sobre el almacenamiento en caché doble, permítanme discutir los problemas que ocurrieron en el proceso de escribir este tablero de dibujo. Como principiante, el problema puede ser de muy bajo nivel, espero que testifiquen.

public class draw extends Canvas implements MouseListener, MouseMotionListener

Al principio, mi clase de mesa de trabajo personalizada heredó la clase Canvas Canvas. Según los datos de la consulta, el método repintado determinará la magnitud del componente, el peso pesado llama al método update () y el peso ligero llama directamente al método paint (). Canvas es un componente pesado, por lo que quiero escribir la tecnología de doble caché en el método update () para facilitar el mantenimiento del código. Después de reescribir update () y ejecutarlo, todavía parpadea. Se encontró que el método update () no fue llamado durante la prueba y la búsqueda de los datos fue infructuosa. Entonces, la solución frente a mí es reescribir reapint () o escribir la tecnología de doble búfer en paint (), considerando sus propios problemas técnicos, elija el segundo.

Después de que se escribió el doble búfer, todavía parpadeaba, pero era un método diferente. Sin almacenamiento en búfer doble, cada gráfico parpadea en secuencia. Después de usar el doble búfer, todo el tablero de dibujo parpadeó y la búsqueda de información falló. Así que intenté cambiar Canvas a JPanel.

public class draw extends JPanel implements MouseListener, MouseMotionListener

En este punto, el problema del parpadeo que me atormentó durante un día se resolvió, pero surgieron dos preguntas para las que no pude obtener la respuesta.

1. ¿Por qué heredo la clase Canvas, cuando llamo al método repaint (), no se llama al método update (), es por herencia?
2. ¿Cuál es la diferencia entre la clase Canvas y la clase JPanel? Sé que Canvas es un componente pesado y JPanel es un componente ligero, ¿tiene algo que ver con esto?

Como principiante, espero que me puedan aconsejar.

Supongo que te gusta

Origin blog.csdn.net/weixin_43797829/article/details/106530283
Recomendado
Clasificación