代码之家  ›  专栏  ›  技术社区  ›  Andreas Dolk

如何等到JComponent完全绘制完毕?

  •  2
  • Andreas Dolk  · 技术社区  · 15 年前

    不幸的是,图像格式化程序从地图中获取当前状态来创建图片,并且有一个机会,特别是当地图变得复杂时,格式化程序在绘制mapBean(JComponent)之前调用。

    尽管用这个openmap应用程序解释了这个问题,但这个问题是相当普遍的,并且应该与Swing相关。现在,我只是等待一个固定的时间(一秒钟),但这并不能消除创建不完整地图的风险。。。

    更多细节-我必须先构建一个(OpenMap)MapPanel,它在内部LZ创建一个MapBean(JComponent子类)和一个MapHandler。然后我向MapHandler提供地理层,框架开始“在”JComponent类型MapBean上绘制地理数据。

    在将所有层添加到地图之后,我使用另一个框架类创建一个JPG图像(或:保存图像数据的字节[])。和 如果我不等待,可能会导致问题:此“图像创建者”根据地图bean的当前状态创建图像,如果我将此“图像创建者”提前调用,则某些地图层未绘制且丢失。很烦人。。。

    3 回复  |  直到 15 年前
        1
  •  4
  •   Tom Hawtin - tackline    15 年前

    java.awt.EventQueue.invokeLater MediaTracker 用于 Image ).

        2
  •  1
  •   Justin    15 年前

     MapBean map = new MapBean();
     map.setData(...);
    
     BufferedImage bi = new BufferedImage(...);
     map.paintComponent(bi.getGraphics());
    
     writeToFile(bi);
    
        3
  •  1
  •   MC Emperor    12 年前

    听起来您需要用Swing的绘制周期同步更新JComponent的底层数据。您可以将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);
                }
            }
        }
    }