点击,出现jLabel文本,但不显示图标图像?

时间:2013-08-02 07:15:12

标签: java swing

当我单击“打印”按钮时,它应显示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);
        }
    });
}   

enter image description here

2 个答案:

答案 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组件(甚至不读取!)。这样你就有了一个方便的机制来更新你的标签。您也可以使用它来更新某些进度条等。