Как дождаться, пока JComponent будет полностью раскрашен?

StackOverflow https://stackoverflow.com/questions/1342932

  •  20-09-2019
  •  | 
  •  

Вопрос

Мне нужен способ дождаться, пока JComponent (Swing) не будет полностью нарисован.Эта актуальная проблема возникает из-за приложения openmap:Задача состоит в том, чтобы нарисовать карту (mapBean) с парой слоев и создать изображение на основе этой карты.

К сожалению, и это четко задокументировано, программа форматирования изображений использует текущее состояние карты для создания изображения, и есть вероятность, особенно когда карты становятся сложными, что программа форматирования вызывается до того, как будет нарисован mapBean, JComponent.

Хотя проблема объясняется с помощью этого приложения openmap, она довольно общая и предположительно связана с Swing.Прямо сейчас я просто жду определенное время (одну секунду), но это не устраняет риск создания неполных карт...

Редактировать

Еще несколько деталей - я должен начать с построения (OpenMap) MapPanel, которая внутренне создает MapBean (подкласс JComponent) и MapHandler.Затем я загружаю в MapHandler географические слои, и Фреймворк начинает отображать географические данные "на" типе JComponent MapBean.

После добавления всех слоев на карту я использую другой класс framework для создания изображения в формате JPG (или:байт[], который содержит данные изображения).И это может возникнуть проблема, если я не подожду:этот "создатель изображений" создает изображение из текущего состояния компонента map, и если я вызову этот "создатель изображений" пораньше, некоторые слои карты не будут закрашены и пропадут.Довольно раздражает...

Это было полезно?

Решение

java.awt.EventQueue.invokeLater позволит вам запустить задачу после завершения операции рисования.Если он выполняет какую-то асинхронную загрузку, то он будет специфичен для API (как MediaTracker делает для Image).

Другие советы

Вы также можете попробовать использовать внеэкранный буфер для рендеринга вашего изображения в:

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

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

 writeToFile(bi);

Похоже, вам нужно синхронизировать обновление базовых данных вашего JComponent с циклом рисования Swing.Вы можете создать подкласс вашего JComponent и украсить paintComponent() метод, вы также могли бы посмотреть на ImageObserver.imageUpdate(), хотя я не уверен, подскажет ли это вам, чего вы хотите.

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);
            }
        }
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top