Reputation: 73
I have a project set up with with an embedded derby jdbc and a jtable, however when I try to append data from my database to my jtable through resultset and adding the results from the resultset to a string[] and adding it to my tablemodel the result display is blank.
This is my database resultset:
ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
while (res.next()) {
String [] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
System.out.print(res.getString("Expenses"));
System.out.print(res.getString("ExpensesType"));
System.out.print(res.getString("PaymentType"));
System.out.print(res.getString("Amount"));
System.out.print(res.getString("Date"));
GUI.tableModel.addRow(row);
GUI.tableModel.fireTableDataChanged();
}
res.close();
This is my table code:
table = new JTable(tableModel);
table.setBackground(Color.GRAY);
table.setFillsViewportHeight(true);
JTableHeader header = table.getTableHeader();
header.setBackground(Color.DARK_GRAY);
header.setForeground(Color.LIGHT_GRAY);
scrollPane.setViewportView(table);
tableModel.addColumn("Expenses");
tableModel.addColumn("Expense Type");
tableModel.addColumn("Payment Type");
tableModel.addColumn("Amount");
tableModel.addColumn("Date");
Upvotes: 1
Views: 110
Reputation: 347184
Since the code, basically, works, I have to assume the problem is with some other part of the application which I cannot replicate, like the database management for example...
However...
Your resource management is non-existent...A database Statement
has context and has a direct relationship to the query that made it, once you have completed working with it you should make sure you close it, for example...
public static Connection createDatabaseConnection() throws SQLException, ClassNotFoundException {
//...
System.out.println("Database Connected...");
try (Statement statement = c.createStatement()) {
count = statement.executeUpdate("CREATE TABLE VAULT (Expenses VARCHAR(5000), ExpensesType VARCHAR(5000), PaymentType VARCHAR(5000), Amount VARCHAR(10), Date VARCHAR(5000))");
System.out.println("Table Created...");
}
try (Statement statement = c.createStatement()) {
ResultSet res = statement.executeQuery("SELECT * FROM VAULT");
while (res.next()) {
String[] row = {res.getString("Expenses"), res.getString("ExpensesType"), res.getString("PaymentType"), res.getString("Amount"), res.getString("Date")};
System.out.print(res.getString("Expenses"));
System.out.print(res.getString("ExpensesType"));
System.out.print(res.getString("PaymentType"));
System.out.print(res.getString("Amount"));
System.out.print(res.getString("Date"));
GUI.tableModel.addRow(row);
}
}
and...
String updateStatement = "INSERT INTO VAULT"
+ " (Expenses, ExpensesType, PaymentType, Amount, Date)"
+ " VALUES (\'" + expenses + "\',\'" + expensesType + "\',\'" + paymentType + "\',\'" + amount + "\',\'" + date + "\')";
try (Statement statement = c.createStatement()) {
System.out.print(updateStatement);
int c = statement.executeUpdate(updateStatement);
count = count + c;
System.out.println("Data Inserted in to Database...");
} catch (Exception ex) {
ex.printStackTrace();
}
This will ensure that once you leave the try
section, the resource will automatically be closed.
You should also consider making use of PreparedStatement
s, see Using Prepared Statements for more details.
In your actionPerformed
method, this...
table.setModel(tableModel);
is worrying. The model has already been set when you setup the UI, you shouldn't need to set it again unless you've create a new model or table, which you've done neither of...
And...
tableModel.fireTableDataChanged();
table.updateUI();
Should never be done. You should never call any of the notification methods of a model externally, these should all be taken care of by the model it self (and in the case of the DefaultTableModel
are).
updateUI
has nothing to do with "updating the state of the UI" and has is probably the most efficient method you could use. The simple fact that you've fireTableDataChanged
should have already triggered an update (although fireTableDataChanged
is also one of the most efficient methods you could use as well).
Simply call tableModel.addRow
and let the model and table do the rest.
Your work flow is a little off. You shouldn't add the row to the table until AFTER you've made sure it's been added to the database, what happens if the insert fails for some reason?
You really, really, REALLY should learn to make use of dialogs, see How to Make Dialogs for more details, instead of throwing, yet, another frame at the user...
static
is not your friend, sure it might "seem" to make life easier and "it's just a quick {what ever}", but bad is bad any of the time...
You should never make UI components static
it is way to easy to lose context and not know if you're updating what's actually on the screen or not.
"But how does class X reference component Y?" - in most cases, it shouldn't. I should either return a value/values that container class can deal with or should communicate through the use of some kind of model or observer pattern...
If you're going to strip away the window frame, you had better implement functionality that allows me to drag it and, because it's a personal grip of mine, resize it, otherwise your users will not like you
Avoid using null
layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
See Why is it frowned upon to use a null layout in Swing? and Laying Out Components Within a Container for more details...
Upvotes: 3