我正在尝试使用下面的方法实现图像,这样当执行发送操作时,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);
}
答案 0 :(得分:2)
在我看来,您的应用程序正在执行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<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 :(得分:1)
你必须将label.setVisible(true);
包裹到invokeLater();
您已从Swing代码中移除Thread.sleep(int)
因为阻止了EDT,然后您遇到Concurency in Swing问题,请创建一个新的void / clas .. Thread
从Runnable
开始,在此代码块中,您可以使用Thread.sleep(int)
暂停流程,并将此处label.setVisible(true);
包含在invokeLater();
中
动画或延迟Swing所需使用javax.swing.Timer
中的任何操作