0

I have a button to print iReport but it take time to display the report so I made a loading frame class called Loading and I am trying to call this class when I press the button but it's not working fine.

My code for button ActionListener is:

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);
        }
    }
}  `
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Nasser Hajlawi
  • 313
  • 2
  • 15
  • 1
    1) Don't block the EDT (Event Dispatch Thread). The GUI will 'freeze' when that happens. See [Concurrency in Swing](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for details and the fix. 2) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) Seems this would be better suited to a `JDialog`. – Andrew Thompson May 04 '17 at 19:51
  • i add `jDialog` but it appear after the report `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 – Nasser Hajlawi May 04 '17 at 20:04
  • 1
    1) Don't put code in comments, where it is virtually unreadable. 2) The important suggest was *before* the one about the `JDialog`. Using a dialog won't fix what's broken (blocking the EDT) in this case. – Andrew Thompson May 04 '17 at 20:12
  • *"Don't put code in comments."* What I forgot to add was.. "Instead [edit] the question to add it." – Andrew Thompson May 04 '17 at 20:42

2 Answers2

4

Like all questions relating to doing long running or blocking tasks in Swing, start with Concurrency in Swing to better understand the problem you're trying to solve. Next take a look at Worker Threads and SwingWorker for the most common solution

For example:

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;
    }

}

Which could then be used something like:

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);

The are a number of variations around the basic idea, so feel free to experiment

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Create New Undecorated frame with loading giffy or loading name.as LoadingScreen.

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                        
            LoadingScreen ls=new LoadingScreen();
     ls.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);
     ls.dispose();
        JasperViewer.viewReport(jasperprint, false);

    } catch (JRException e) {
        JOptionPane.showMessageDialog(this, e);

    } finally {
        try {
            rs.close();
            pst.close();

        } catch (SQLException ex) {
            Logger.getLogger(showAllInvoices.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}  

I hope this will run

nircraft
  • 8,242
  • 5
  • 30
  • 46
SBhadane
  • 1
  • 2