如何使用线程显示动画GIF图像

我正在尝试使用下面的方法实现一个图像,这样当执行发送操作时,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上进行实际工作,而您的线程负责显示和隐藏进度标签。 我可能错了,但如果是这样,那么我建议你做与你正在做的完全相反的事情。 更新SWING组件只能从EDT(事件调度线程)完成,而不能用其他线程完成。

如果这是一个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 { 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 ,在这个代码块里面你可以暂停进程(es )通过使用Thread.sleep(int)并在此处label.setVisible(true); 包装到invokeLater();

动画或延迟Swing要求使用javax.swing.Timer中的任何动作