【问题标题】:How do I load an animated GIF within my JFrame while a long process is running?如何在运行长进程时在 JFrame 中加载动画 GIF?
【发布时间】:2016-01-12 19:14:36
【问题描述】:

问题 当一个按钮被点击时,它需要弹出一个加载GIF,而执行的过程很长。该过程完成后,此弹出窗口会自动关闭。

我的方法

    if (evt.getSource() == processButton) {

            ImageIcon loading = new ImageIcon("img/loading.gif");
            final JLabel loaderLabel = new JLabel("loading", loading, JLabel.CENTER);
            Thread t = new Thread(new Runnable() {

                @Override
                public void run() {
                    ProcessFrame.this.frame.add(loaderLabel);
                }

            });
        process(); // long process
        loaderLabel.setVisible(false);
    }

ProcessFrame 是用户与之交互的主要 JFrame。

我遇到了什么问题?

加载图像永远不会弹出(或至少作为标签)。关注了一些关于 SO 的帖子,但到目前为止是徒劳的。我哪里错了?

替代方案

使用 SwingWorker。但是,鉴于进程正在执行,我如何知道 SLEEP_TIME?或者更准确地说,我何时以及如何将 SwingWorker 与运行的 process() 方法集成?

  SwingWorker<Void, Void> mySwingWorker = new SwingWorker<Void, Void>(){
     @Override
     protected Void doInBackground() throws Exception {

        Thread.sleep(SLEEP_TIME);
        return null;
     }
  };

【问题讨论】:

  • 您是否有任何理由将标签从单独的线程添加到框架?为什么不简单地将它添加到框架中(没有线程)?
  • 是的,因为不这样做会影响 EDT,并且没有观察到任何变化。 stackoverflow.com/questions/12566311/…
  • 那么您需要使用与您的 GUI 线程正确同步的线程。使用SwingUtilities.invokeLater 而不是使用常规的Thread
  • 您的阻塞进程也在您的 GUI 线程上运行,因此您的 GUI 线程将完全阻塞。您需要使用单独的Thread 来阻止进程。
  • 对于example

标签: java swing jframe swingworker


【解决方案1】:

这...

Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        ProcessFrame.this.frame.add(loaderLabel);
    }
});

这是一个坏主意,因为您违反了 Swing 的单线程规则(而且您永远不会启动 Thread

应该更像...

ProcessFrame.this.frame.add(loaderLabel);
ProcessFrame.this.frame.revalidate();
ProcessFrame.this.frame.repaint();

然后您应该在SwingWorker 中运行process(); // long process,使用它的PropertyChangeSupport 来确定工作人员何时完成,作为example

【讨论】:

    【解决方案2】:

    我解决了这个问题。所以我在这里发布我对自己问题的解决方案。感谢之前的cmets。希望这可以帮助遇到同样问题的人。

    JDialog loadingDialog = new JDialog();
    
    public void createDialog(JDialog d) {
    
        JLabel l = new JLabel(new ImageIcon(("img/loading.gif")));
        d.setSize(100, 100);
        d.add(l);
        d.setVisible(true);
        d.isAlwaysOnTop();
    }
    // other methods ... and now defining ActionPerformed method for the button below
    private void processButtonActionPerformed(ActionEvent evt) {
        if (evt.getSource() == processButton) {
            createDialog(dialogLoading);
            SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
            @Override
                protected Boolean doInBackground() throws Exception {
                    process(); // this is the long process
                    return true;
                }   
                protected void done() {
                    boolean status;
                    try {
                        status = get();
                        dialogLoading.setVisible(false);
                    } catch (InterruptedException e) {
                        // This is thrown if the thread's interrupted.
                    } catch (ExecutionException e) {
                        // This is thrown if we throw an exception
                        // from doInBackground.
                    }
                }
           };
           worker.execute();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 2018-03-20
      • 2020-01-29
      • 2013-08-04
      • 1970-01-01
      • 2010-11-21
      • 2021-10-24
      相关资源
      最近更新 更多