2012-08-15 16 views
7

Aquí hay un ejemplo simple de dibujar un óvalo.¿Por qué swing draw componente simple dos veces?

public class SwingPainter extends JFrame{ 
    public SwingPainter() { 
     super("Swing Painter"); 
     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     getContentPane().add(new MySwingComponent()); 

     setSize(200, 200); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new SwingPainter(); 
    } 

    class MySwingComponent extends JComponent { 

     public void paintComponent(Graphics g) { 
      System.out.println("paintComponent"); 
      super.paintComponent(g); 
      g.setColor(Color.red); 
      g.fillOval(10, 10, 50, 50); 
     } 

     @Override 
     protected void paintBorder(Graphics g) { 
      System.out.println("Paint border"); 
      super.paintBorder(g); 
     } 

     @Override 
     protected void paintChildren(Graphics g) { 
      System.out.println("Paint children"); 
      super.paintChildren(g); 
     } 
    } 
} 

Pero en modo de depuración o añadir algo de información a la consola antes de dibujar (como en el ejemplo), se puede ver que la oscilación se basa componentes dos veces.

paintComponent

fronterizas pintura

niños pintura

paintComponent

fronterizas pintura

niños pintura

No puedo entender por qué sucede, pero creo que puede afectar el rendimiento en una GUI difícil.

+0

posible duplicado de http://stackoverflow.com/questions/4814289/why-is-my-code-executing-paintcomponentgraphics-page-twice –

+0

posible duplicado de [paintComponent se está ejecutando dos veces] (http: // stackoverflow. com/questions/4800885/paintcomponent-is-executing-twice) –

Respuesta

9

El artículo Painting in AWT and Swing: Additional Paint Properties: Opacity sugiere por qué: "La propiedad opaca permite que el sistema de pintura de Swing detecte si una solicitud de repintado en un componente en particular requerirá el repintado adicional de antepasados ​​subyacentes o no". Como extiende JComponent, la propiedad opaque es falsa de forma predeterminada y la optimización no es posible. Establezca la propiedad true para ver la diferencia, así como el artefacto de no respetar la propiedad. Se pueden encontrar ejemplos relacionados here y here.

+0

Sí, tienes razón. Es a causa de opaco. Cuando lo configuro como verdadero, solo 3 registros están en la salida de la consola. Necesito investigar el trabajo opaco más a fondo :) – Dragon

2

Estoy de acuerdo con Konstantin, lo que necesita recordar, el administrador de repintado responde a cualquier cantidad de solicitudes cuando se inicia la aplicación, esto normalmente incluye la solicitud de pintura inicial cuando se muestra y cambia el tamaño de la ventana (hay dos).

Pruebe esto. Espere hasta que la aplicación se esté ejecutando y cambie el tamaño de la ventana. Estoy seguro de que obtendrá más de un par de solicitudes de repintado;)

2

Esto funciona bien para mí. De hecho, incluso en modo de depuración la salida fue:

paintComponent 
Paint border 
Paint children 

Por favor, tenga en cuenta que en los componentes AWT y Swing hay muchos métodos (pintura, paintBorder, paintChildren, paintComponent, volver a pintar, y otros) que son llamados mediante devolución de llamada, siempre que el motor de la GUI considere adecuado. Eso puede variar de JVM a JVM o incluso de diferentes sesiones de ejecución. También pueden activarse desde la interacción con su programa (si minimiza/maximiza, por ejemplo). O pueden no, en absoluto.

Cuestiones relacionadas