2017-05-04 115 views
0

我有一个按钮来打印iReport,但它需要时间来显示报告,所以我做了一个加载框架类叫Loading ,我试图调用这个类,当我按下按钮,但它不能正常工作。显示'正在加载'框架,直到后台进程完成

我对按钮ActionListener代码:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {           
    loading.setVisible(true);// show frame before trying to connect to database and load report 
    try { 
     String reportquery = "Select * from invoices "; 
     JasperDesign jasperdesign = JRXmlLoader.load("StatementReport.jrxml"); 
     JRDesignQuery designquery = new JRDesignQuery(); 
     designquery.setText(reportquery); 
     jasperdesign.setQuery(designquery); 
     JasperReport jasperreport = JasperCompileManager.compileReport(jasperdesign); 
     JasperPrint jasperprint = JasperFillManager.fillReport(jasperreport, null, con); 

     JasperViewer.viewReport(jasperprint, false); 

    } catch (JRException e) { 
     JOptionPane.showMessageDialog(this, e); 
    } finally { 
     try { 
      rs.close(); 
      pst.close(); 
      loading.dispose(); // dispose loading frame when finish 
     } catch (SQLException ex) { 
      Logger.getLogger(showAllInvoices.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} ` 
+1

1)不要阻塞EDT(Event Dispatch Thread)。发生这种情况时,GUI将“冻结”。有关详细信息和修补程序,请参见[Swing中的并发](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/)。 2)请参阅[使用多个JFrames,好/坏实践?](http://stackoverflow.com/q/9554636/418556)似乎这将更适合'JDialog'。 –

+0

我添加'jDialog',但它出现在报告 'jDialog.setLayout(new GridBagLayout()); jDialog.add(new JLabel(“Please wait ...”)); jDialog.setMinimumSize(new Dimension(150,50)); jDialog.setResizable(false); jDialog.setModal(false); jDialog.setUndecorated(true); jDialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); jDialog.setLocationRelativeTo(null); jDialog.setVisible(true);'@AndrewThompson –

+1

1)不要把代码放在注释中,它几乎不可读。 2)重要的建议是在* JDialog之前。在这种情况下,使用对话框不会修复损坏的东西(阻止EDT)。 –

回答

2

喜欢与做长时间运行或在振荡闭锁任务的所有问题,开始Concurrency in Swing更好地了解你正在试图解决这个问题。接下来看看Worker Threads and SwingWorker最常见的解决方案

例如:

public static class JasperReportsWorker extends SwingWorker<JasperReport, JasperReport> { 

    @Override 
    protected JasperReport doInBackground() throws Exception { 
     JasperReport report = null; 
     try { 
      String reportquery = "Select * from invoices "; 
      JasperDesign jasperdesign = JRXmlLoader.load("StatementReport.jrxml"); 
      JRDesignQuery designquery = new JRDesignQuery(); 
      designquery.setText(reportquery); 
      jasperdesign.setQuery(designquery); 
      report = JasperCompileManager.compileReport(jasperdesign); 
     } finally { 
      try { 
       rs.close(); 
       pst.close(); 
      } catch (SQLException ex) { 
       ex.printStackTrace(); 
      } 
     } 
     return report; 
    } 

} 

然后可以使用类似:

JasperReportsWorker worker = new JasperReportsWorker(); 
JDialog dialog = new JDialog(); 
dialog.setModal(true); 
dialog.add(new JLabel("Working...")); 
dialog.pack(); 
dialog.setLocationRelativeTo(null); 
worker.addPropertyChangeListener(new PropertyChangeListener() { 
    @Override 
    public void propertyChange(PropertyChangeEvent evt) { 
     String name = evt.getPropertyName(); 
     JasperReportsWorker worker = (JasperReportsWorker) evt.getSource(); 
     if ("state".equalsIgnoreCase(name)) { 
      switch (worker.getState()) { 
       case DONE: 
        if (dialog != null) { 
         dialog.setVisible(false); 
        } 
        try { 
         JasperReport report = worker.get(); 
         JasperPrint jasperprint = JasperFillManager.fillReport(jasperreport, null, con); 
         JasperViewer.viewReport(jasperprint, false); 
        } catch (InterruptedException | ExecutionException ex) { 
         ex.printStackTrace(); 
        } 
        break; 
      } 
     } 
    } 
}); 
worker.execute(); 
dialog.setVisible(true); 

的一些周围的基本思想变化,请随时尝试

相关问题