Domanda

Ho bisogno di un modo di aspettare fino a quando un (Swing) JComponent è completamente dipinta. Questo problema reale deriva da un'applicazione openmap:. Il compito è quello di disegnare una mappa (mapBean) con un paio di strati e di creare un'immagine da quella mappa

Purtroppo, ed è chiaramente documentato, il formattatore immagine assume lo stato attuale dalla mappa per creare l'immagine, e c'è una possibilità, soprattutto quando le mappe diventano complesse, che l'IST formattatore chiamato prima della mapBean, un JComponent, è dipinto .

Anche se spiegato con questa applicazione openmap, il problema è del tutto generale e presumibilmente swing correlate. In questo momento, ho solo aspettare un tempo fisso (un secondo), ma che non elimina il rischio di creare mappe incomplete ...

Modifica

Alcuni dettagli - devo iniziare con la costruzione di un (OpenMap) MapPanel, che crea un internallz MapBean (JComponent sottoclasse) e una MapHandler. Poi mi nutro la MapHandler con i livelli geografici e il quadro inizia a dipingere i dati geografici 'on' il tipo JComponent MapBean.

Dopo aver aggiunto tutti i livelli alla mappa, io uso un'altra classe framework per creare un'immagine JPG (o: il byte [] che contiene i dati di immagine). E questo può causare problemi, se non mi aspetto: questo 'immagine creatore' crea l'immagine dallo stato attuale della mappa di fagioli, e se io chiamo questo 'immagine creatore' ai primi, un po ' i livelli della mappa non sono dipinte e dispersi. Piuttosto fastidioso ...

È stato utile?

Soluzione

java.awt.EventQueue.invokeLater vi permetterà di eseguire un compito dopo l'operazione di disegno è terminato. Se si sta facendo qualche tipo di carico asincrono, allora sarà specifico API (come MediaTracker fa per Image).

Altri suggerimenti

Si potrebbe anche provare a utilizzare un buffer schermo spento per rendere la vostra immagine in:

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

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

 writeToFile(bi);

Sembra che tu abbia bisogno di sincronizzare l'aggiornamento dei dati sottostanti del JComponent con ciclo di verniciatura di Swing. È possibile creare una sottoclasse tua JComponent e decorare il metodo paintComponent(), si potrebbe anche guardare ImageObserver.imageUpdate(), anche se non sono sicuro se che sta per dirti quello che vuoi.

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);
            }
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top