如何在长时间进程运行时在JFrame中加载动画GIF?

时间:2016-01-11 11:06:23

标签: java swing jframe swingworker

问题 单击一个按钮时,需要弹出一个加载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;
     }
  };

2 个答案:

答案 0 :(得分:2)

此...

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

然后,您应该使用process(); // long processSwingWorker中运行PropertyChangeSupport,以确定工作人员何时结束,example

答案 1 :(得分:0)

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

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