当我单击“打印”按钮时,它应显示Gif动画,然后显示“正在工作...”文本。 但这里只出现“Working ...”文字,而不是动画。
以下是代码:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jLabel1.setVisible(true);
/* This portion is Time Consuming so I want to display a Loading gif animation. */
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
empPrint=new HashMap();
if(!empPrint.isEmpty())
empPrint.clear();
if(jRadioButton1.isSelected())
empPrint.put("PNO",parent.emp.getPAN());
else
empPrint.put("PNO",records.get(jComboBox1.getSelectedItem()));
REPORT="Report.jrxml";
try {
JASP_REP =JasperCompileManager.compileReport(REPORT);
JASP_PRINT=JasperFillManager.fillReport(JASP_REP,empPrint,parent.di.con);
JASP_VIEW=new JasperViewer(JASP_PRINT,false);
JASP_VIEW.setVisible(true);
JASP_VIEW.toFront();
}
catch (JRException excp) {
}
setVisible(false);
}
});
}
答案 0 :(得分:4)
您应该使用SwingWorker来执行耗时的任务。使用invokeLater()
只需将其推送到事件队列,它就会在EDT中运行,阻塞它。
在事件调度线程中完成了swing的绘制,但由于EDT正在忙于运行您的打印任务,因此swing无法处理重绘请求。
// Note the upped case "Void"s
SwingWorker worker = new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() {
// Do the printing task here
return null;
}
@Override
public void done() {
// Update the UI to show the task is completed
}
}.execute();
答案 1 :(得分:1)
在这种情况下,SwingUtilities.invokeLater()
方法无法帮助您。您传递的Runnable
仍会在事件调度线程(EDT,负责绘制UI并响应点击等的线程)上执行。
您可以查看SwingWorkers,但您也可以使用简单的ExecutorService
并将Runnable
传递给那里。 Executor框架 - 在Java 5或6中添加 - 提供了相对简单易用的工具,可以在后台运行,而不必担心自己的线程。我建议使用这样的东西(伪代码):
private ExecutorService executor = Executors.newFixedExecutorService()
....
public void buttonPressed() {
label.setVisible(true);
...
executor.submit(new Runnable() {
// create the report etc.
// DO NOT ACCESS ANY UI COMPONENTS FROM HERE ANYMORE!
// ...
SwingUtilities.invokeLater(new Runnable() {
// update the UI in here
label.setVisible(false);
});
});
}
如您所见,此处也使用SwingUtilities.invokeLater
。但是,它从后台线程调用,以确保您的UI代码在EDT上而不是在后台线程上执行。这就是它的设计目标,因为永远不能从后台线程访问UI组件(甚至不读取!)。这样你就有了一个方便的机制来更新你的标签。您也可以使用它来更新某些进度条等。