2013-04-21 107 views
1

问题是,我的SwingWorker没有按照我的意图去做,我将在这里使用一些简化的代码示例,它们与我的代码类似,但没有讨厌的不相关的细节。java swingworker没有更新图形用户界面

我在我的情况下,两个类:扩展的JPanel延伸的JPanel

的想法是,mainPanel中是一个占位符类

  1. 的mainPanel
  2. GalleryPanel和动态运行时我添加其他JPanel的它(并删除旧的)。

    ,做工作的代码,从mainPanel中类中采取:

    这里的问题是,创建GalleryPanel是相当缓慢(>一秒),我想展示一些负载循环,再加防止它阻止了图形用户界面,所以我将其改为:

    public void initGalleryPanel() { 
        this.removeAll(); 
    
        double availableWidth = this.getSize().width; 
        double availableHeight = this.getSize().height; 
    
        double width = GamePanel.DIMENSION.width; 
        double height = GamePanel.DIMENSION.height; 
    
        double widthScale = availableWidth/width; 
        double heightScale = availableHeight/height; 
        final double scale = Math.min(widthScale, heightScale); 
    
        new SwingWorker<GalleryPanel, Void>() { 
         @Override 
         public GalleryPanel doInBackground() { 
          return new GalleryPanel(scale); 
         } 
    
         @Override 
         public void done() { 
          try { 
           add(get()); 
          } catch (InterruptedException | ExecutionException ex) { 
           Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); 
          } 
         } 
        }.execute();   
    
        revalidate(); 
        repaint(); 
    } 
    

    但是现在GalleryPanel不再显示了,任何帮助将不胜感激。

    其他信息:GalleryPanel的实例创建需要很长的时间,因为它会呈现它应该在瞬间显示的内容,例如paintComponent只能绘制该图像。

    问候。

回答

5

您对revalidate()repaint()通话瞬间发生和GalleryPanel不得不之前创建或加入一个机会:

@Override 
    public void done() { 
     try { 
      add(get()); 
     } catch (InterruptedException | ExecutionException ex) { 
      Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
}.execute();   

revalidate(); 
repaint(); 

尝试,而不是从done()方法在作出这些呼叫,您添加后新组件:

@Override 
    public void done() { 
     try { 
      add(get()); 
      revalidate(); 
      repaint(); 
     } catch (InterruptedException | ExecutionException ex) { 
      Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
}.execute();   
+0

非常感谢。这实际上是一个小错误,我知道从正常执行切换到后台执行时应该更加小心。 – skiwi 2013-04-21 16:47:38

+0

@skiwi:不客气。魔鬼总是在细节中。 – 2013-04-21 16:49:42

+0

@Hovercraft Full Of Eels +1,但请真的(我的观点)好实践添加/删除/修改容器(重新验证和重绘)或其工作线程内的JComponents, – mKorbel 2013-04-21 17:38:56