Как показать анимированное GIF-изображение, используя поток - PullRequest
1 голос
/ 11 октября 2011

Я пытаюсь реализовать изображение, используя метод, описанный ниже, чтобы при выполнении действия отправки изображение GIF отображалось в течение заданного времени (как реализовано методом паузы threadRunner).

Проблема в том, что он не показывает. И при тестировании, когда я отключаю 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);
    } 

Ответы [ 2 ]

2 голосов
/ 11 октября 2011

Мне кажется, что ваше приложение выполняет фактическую работу с EDT, а ваш поток заботится о том, чтобы показывать и скрывать метку прогресса. Я могу ошибаться, но если это так, то я бы порекомендовал вам сделать полную противоположность того, что вы делаете. Обновление компонентов SWING должно выполняться только из EDT (Thread Dispatch Thread), а не из других потоков.

Если это настольное приложение 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.

1 голос
/ 11 октября 2011

Вы должны обернуть label.setVisible(true); в invokeLater();

вы удалили Thread.sleep(int) из кода Swing, потому что блокировали EDT, тогда у вас есть проблема с Concurency в Swing , создайте новый void / clas .. с Thread, начиная с Runnable, и внутри этого блока кода вы можете приостановить процесс (ы), используя Thread.sleep(int) и поместить сюда label.setVisible(true);, включая invokeLater(); тоже

Для анимации или задержки любого из действий в Swing требуется использование javax.swing.Timer

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...