1

基本上问题是我的 SwingWorker 没有做我想做的事,我将在这里使用一些简化的代码示例,这些示例与我的代码相似,但没有令人讨厌的不相关细节。

在我的案例中,我有两个课程:

  1. MainPanel 扩展 JPanel
  2. GalleryPanel 扩展 JPanel

这个想法是 MainPanel 是一个占位符类,并且在运行时动态地我将其他 JPanel 添加到它(并删除旧的)。

有效的代码,取自 MainPanel 类内部:

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);

    add(new GalleryPanel(scale));

    revalidate();
    repaint();
}

这里的问题是创建 GalleryPanel 非常慢(> 1 秒),我想显示一些加载圈并防止它阻塞 GUI,所以我将其更改为:

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 只能绘制该图像。

问候。

4

1 回答 1

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();        
于 2013-04-21T16:43:23.567 回答