簡體   English   中英

如何使用線程顯示動畫GIF圖像

[英]How do I show a animated GIF image using a thread

我正在嘗試使用以下方法實現圖像,以便在執行send操作時,GIF圖像應在指定時間內顯示(由threadRunner pause方法實現)。

問題是它沒有顯示。 在測試中,當我禁用stop()時,它與delIveryReport Textarea同時出現,而不應該出現。 我該如何解決這個問題。

 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

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上進行實際工作,而您的線程負責顯示和隱藏進度標簽。 我可能是錯的,但是如果是這樣,那么我建議您做的事情與您做的完全相反。 僅應從EDT(事件調度線程)完成SWING組件的更新,而不能從其他線程進行更新。

如果這是一個SWING桌面應用程序,那么我的建議是讓您看一下SwingWorker,這是一個專門設計用於處理長時間運行的任務而又不會阻塞EDT的類。 然后,您可以執行以下概述的操作(我的代碼可能無法100%編譯,但是它應該使您了解我的意思。

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應該注意顯示它。 只要您的SMS發送代碼在另一個線程上運行,SWING應該很高興能夠渲染GIF動畫而不會被SMS發送代碼阻止。

您必須包裝label.setVisible(true); 進入invokeLater();

您已經從Swing代碼中刪除Thread.sleep(int) ,因為它阻止了EDT,那么您在Swing中的Concurency出現了問題,創建了一個新的void / clas ..從Runnable開始的Thread ,並且在此代碼塊中,您可以暫停進程),方法是使用Thread.sleep(int)並將其放在此處label.setVisible(true); 包裝到invokeLater();

動畫或在Swing中延遲任何動作,要求使用javax.swing.Timer

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM