1

当我单击打印按钮时,它应该显示一个 Gif 动画,后跟文本“Working...”,但这里只出现文本“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);
        }
    });
}   

在此处输入图像描述

4

2 回答 2

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();
于 2013-08-02T07:18:58.610 回答
1

在这种情况下,该SwingUtilities.invokeLater()方法对您没有帮助。您传递的Runnable仍然在事件调度线程(EDT,负责绘制 UI 和响应点击等的线程)上执行。

您可以查看 SwingWorkers,但您也可以使用简单ExecutorService的并将 the 传递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 组件。这样你就有一个方便的机制来更新你的标签。您还可以使用它来更新一些进度条等。

于 2013-08-02T07:41:52.327 回答