2017-05-04 84 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); 

的一些周圍的基本思想變化,請隨時嘗試

相關問題