首先,资源管理…
如果可以,您应该只打开与数据库的单个连接。确保在关闭应用程序之前将其关闭。连接过程可能会很昂贵,因此您只在确实必须这样做时才真正想要这样做。
You close your resources once you have finished with them. This is best
achieved by using a
try-finallyblock…
private Connection con;protected void close() throws SQLException { if (con != null) { con.close(); }}protected Connection getConnection() throws ClassNotFoundException, SQLException { if (con == null) { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String url = "jdbc:odbc:*****"; String user = "******"; String pass = "******"; Connection con = DriverManager.getConnection(url, user, pass); } return con;}private void search() throws Exception { Statement state = null; ResultSet rs = null; try { state = getConnection().createStatement(); rs = state.executeQuery("SELECt " + "pIDNo AS 'Patient ID'," + "pLName AS 'Last Name'," + "pFName AS 'First Name'," + "pMI AS 'M.I.'," + "pSex AS 'Sex'," + "pStatus AS 'Status'," + "pTelNo AS 'Contact No.'," + "pDocID AS 'Doctor ID'," + "pAddr AS 'St. No.'," + "pStreet AS 'St. Name'," + "pBarangay AS 'Barangay'," + "pCity AS 'City'," + " pProvince AS 'Province'," + " pLNameKIN AS 'Last Name'," + "pFNameKIN AS 'First Name'," + "pMIKIN AS 'M.I.'," + "pRelationKIN AS 'Relation'," + "pTotalDue AS 'Total Due'" + " FROM dbo.Patients"); ResultSetmetaData rsmetadata = rs.getmetaData(); int columns = rsmetadata.getColumnCount(); DefaultTableModel dtm = new DefaultTableModel(); Vector column_name = new Vector(); Vector data_rows = new Vector(); for (int i = 1; i < columns; i++) { column_name.addElement(rsmetadata.getColumnName(i)); } dtm.setColumnIdentifiers(column_name); while (rs.next()) { data_rows = new Vector(); for (int j = 1; j < columns; j++) { data_rows.addElement(rs.getString(j)); } dtm.addRow(data_rows); } tblPatient.setModel(dtm); } finally { try { rs.close(); } catch (Exception e) { } try { state.close(); } catch (Exception e) { } }}Now to the problem at hand…
It appears you have create two references to
con. One as class field and one
as a method variable (in
search).
You are then passing
conto Jasper Reports, which I suspect is
null.
Instead you should use the
getConnection()as outlined above.
public void reportviewer() { try{ String report = "C:\Users\cleanfuel\documents\NetBeansProjects\StringManipulation\src\stringmanipulation\report1.jrxml"; JasperReport jasp_report = JasperCompileManager.compileReport(report); JasperPrint jasp_print = JasperFillManager.fillReport(jasp_report, null, getConnection()); JasperViewer.viewReport(jasp_print); } catch (Exception e) { e.printStackTrace(); }}Updated with background worker…
A report can take some time to compile and fill. You should off load this work
to a background thread so it doesn’t interfere with your UI (or make it look
like you application as hung).
The simplest solution would be to use a
SwingWorker. It has functionality to
resync the threads with the UI
public void reportviewer() { // Disable any UI components you don't want the user using while // the report generates... new ReportWorker().execute();}public class ReportWorker extends SwingWorker<JasperPrint, Void> { @Override protected JasperPrint doInBackground() throws Exception { String report = "C:\Users\cleanfuel\documents\NetBeansProjects\StringManipulation\src\stringmanipulation\report1.jrxml"; JasperReport jasp_report = JasperCompileManager.compileReport(report); JasperPrint jasp_print = JasperFillManager.fillReport(jasp_report, null, getConnection()); return jasp_print; } @Override protected void done() { try { JasperPrint jasp_print = get(); JasperViewer.viewReport(jasp_print); } catch (Exception exp) { exp.printStackTrace(); } // Renable any UI components you disabled before the report run }}Take a look at Concurrency in
Swing for more
details.
Hints
If you can pre-compile the report and load it (rather the loading the XML), it
will make the report process quicker.



