Pregunta

Necesito una manera que esperar hasta que un (Swing) JComponent está totalmente pintado. Este problema real surge de una aplicación OpenMap:. La tarea consiste en dibujar un mapa (mapBean) con un par de capas y crear una imagen a partir de ese mapa

Por desgracia, y está claramente documentado, el formateador imagen ocupa el estado actual del mapa para crear la imagen, y hay una oportunidad, sobre todo cuando los mapas se vuelven complejas, que el ist formateador llamada antes de que el mapBean, un JComponent, se pinta .

A pesar de que se ha explicado con esta aplicación OpenMap, el problema es bastante general y supuestamente relacionada oscilación. En este momento, sólo tiene que esperar un tiempo fijo (un segundo), pero que no elimina el riesgo de crear mapas incompletos ...

Editar

Algunos detalles más - que tienen que empezar con la construcción de un (OpenMap) MapPanel, lo que crea una internallz MapBean (JComponent subclase) y un MapHandler. Entonces me alimento del MapHandler con capas geográficas y el Marco comienza a pintar los datos geográficos 'en' la MapBean tipo JComponent.

Después de añadir todas las capas al mapa, utilizo otra clase marco para crear una imagen JPG (o: el byte [] que contiene los datos de la imagen). Y este puede causar un problema, si no esperar: este 'creador de imágenes' crea la imagen del estado actual de la haba de mapa, y si esto lo llamo 'creador de imágenes' a principios, algunos las capas del mapa no están pintadas y desaparecidos. Bastante molesto ...

¿Fue útil?

Solución

java.awt.EventQueue.invokeLater le permite llevar a cabo una tarea después de la operación ha terminado de pintura. Si lo está haciendo algún tipo de carga asíncrona, entonces será API específica (como se hace para MediaTracker Image).

Otros consejos

También puede intentar usar un buffer fuera de pantalla para representar la imagen en:

 MapBean map = new MapBean();
 map.setData(...);

 BufferedImage bi = new BufferedImage(...);
 map.paintComponent(bi.getGraphics());

 writeToFile(bi);

Parece que usted necesita para sincronizar la actualización de los datos subyacentes de su ciclo de JComponent con pintura de oscilación. Usted puede subclase el JComponent y decorar el método paintComponent(), también se podría hacer en ImageObserver.imageUpdate(), aunque no estoy seguro de si eso va a decir lo que quiera.

public class DrawingCycleAwareComponent extends MyOtherJComponent {

    private final Object m_synchLock = new Object();

    protected void paintComponent(Graphics g) {
        synchronized (m_synchLock) {
            super.paintComponent(g);
        }
    }

    protected void updateData(Object data) {
        if (SwingUtilities.isEventDispatchThread()) {
            reallySetMyData(data);  // don't deadlock yourself if running in swing
        }
        else {
            synchronized (m_synchLock) {
                reallySetMyData(data);
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top