如何使用线程显示动画GIF图像 [英] How do I show a animated GIF image using a thread

查看:138
本文介绍了如何使用线程显示动画GIF图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用下面的方法实现图像,这样当执行发送操作时,GIF图像应该在指定的时间内显示(由threadRunner暂停方法实现)。

I am trying to implement an image using the method below, so that when the send action is performed, the GIF image should show within a specified time(As implemented by the threadRunner pause method).

问题是它没有显示。在测试时,当我禁用stop()时,它与delIveryReport Textarea同时出现,而不应该是。我该如何解决这个问题。

The problem is it doesn't show. And on testing, when I disable the stop() it appears at the same time as delIveryReport Textarea which shouldn't be. How do I solve this.

 private void sendActionPerformed(java.awt.event.ActionEvent evt) {              

            threadRunner t = new threadRunner();
            String fone = "";
            SendSMS sms = new SendSMS();
            String[] arMSISDN = msisdn.split(",");
            for (int i = 0; i < arMSISDN.length; i++) {

                fone = arMSISDN[i];
                fone = fone.trim();
                try {

                    Cursor cursor = new Cursor(Cursor.WAIT_CURSOR);
                    setCursor(cursor);
                    t.pause(loading);

                    sms.sendSMS(user, pass, fone, senderIDString, msgString);


                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    Cursor normal = new Cursor(Cursor.DEFAULT_CURSOR);
                    setCursor(normal);
                    t.stop(loading);
                    deliveryReport.append(fone + ": " + sms.response + "\n");
                }

            }

    //        JOptionPane.showMessageDialog(rootPane, deliveryReport);
            deliveryReport.setVisible(true);
            jScrollPane2.setVisible(true);



            redo.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
            redo.setForeground(new java.awt.Color(223, 90, 46));
            redo.setText("Would you like to send another Message?");
            yes.setEnabled(true);
            no.setEnabled(true);
            yes.setText("Yes");
            no.setText("No");
            back.setEnabled(false);
            send.setEnabled(false);


        } 

THREADRUNNER

THREADRUNNER

public void pause(JLabel label){

        try {
            Thread.sleep(5000);
            label.setVisible(true);    
        } catch (InterruptedException ex) {
            Logger.getLogger(threadRunner.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void stop(JLabel l){
        l.setVisible(false);
    } 


推荐答案

在我看来,你的应用程序正在EDT上执行实际工作,而您的线程负责显示和隐藏进度标签。我可能错了,但如果是这样,那么我建议你做与你正在做的完全相反的事情。更新SWING组件只能从EDT(事件调度线程)完成,而不是其他线程。

It seems to me that your application is doing the actual work on the EDT, while your thread takes care of showing and hiding the progress label. I might be wrong, but if that is the case, then I'd recommend that you do the complete opposite of what you are doing. Updating SWING components should only be done from the EDT (Event Dispatch Thread) and no other threads.

如果这是一个SWING桌面应用程序,那么我的建议是你看看SwingWorker,这是一个专门设计用于处理长时间运行任务而不阻止EDT的类。然后你可以做下面概述的事情(我的代码可能不会100%编译,但它应该让你知道我的意思。

If this is a SWING desktop application, then my recommendation would be that you take a look at SwingWorker which is a class that is specifically designed to handle long running tasks withough blocking the EDT. You could then do something like outlined below (my code might not compile 100%, but it should give you an idea of what i mean.

private void sendActionPerformed(java.awt.event.ActionEvent evt) {  
  //implement code to show progress label here
  SMSWorker w = new SMSWorker(user, pass, senderIdString, msgString, msisdn.split(","));
  w.execute();
}

public SMSWorker extends SwingWorker<Void, DeliveryReport> {

  private final String user;
  private final String pass;
  private final String senderIdString;
  private final String msgString;
  private final String[] arMSISDN;

  // this constructor runs on the current (EDT) thread.
  public SMSWorker(String user, String pass, String senderIdString, String msgString, String[] arMSISDN) {
    this.user = user;
    this.pass = pass;
    this.senderIdString = senderIdString;
    this.msgString = msgString;
    this.arMSISDN = arMSISDN;
  }

  // this function runs in a separate thread.
  public Boolean doInBackground() {

       // Instantiate SMS gateway client.
       SendSMS sms = new SendSMS();

       // Assuming a delivery report can be created like this.
       DeliveryReport deliveryReport = new DeliveryReport();

       for (int i = 0; i < arMSISDN.length; i++) {

            fone = arMSISDN[i];
            fone = fone.trim();
            try {
                sms.sendSMS(user, pass, fone, senderIDString, msgString);

            } catch (Exception e) {
                // you can notify users about exception using the publish() method.

            } finally {
                deliveryReport.append(fone + ": " + sms.response + "\n");
            }

        }

        return deliveryReport;

  }

  // this function runs on the current (EDT) thread.
  public void done() {
    try {
      // synchronize worker thread with EDT.
      DeliveryReport deliveryReport = get();
    } catch (Exception e) {
      //implement code to notify user about errors here.
    } finally {
      //implement code to hide progress label here.
    }
}

至于你的问题:只需设置动画gif为JLabel的图标 - 和SWING应该照顾它。只要你的短信发送代码在另一个线程上运行,SWING就应该能够呈现GIF动画,而不会被短信发送代码阻止。

As for your question : just set the animated gif as the JLabel's icon - and SWING should take care of showing it. As long as your SMS sending code runs on another thread, SWING should happily be able to render the GIF animations without being blocked by the SMS sending code.

这篇关于如何使用线程显示动画GIF图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆