I created a java swing application, which takes data from a database, and displays it in a JTable. I'm currently just trying to view all the data in my database. But when I click the button to send the query to the database and view the obtained data on the jtable, the table does not update. This is my code:
TableData.java
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
public class TableData extends JPanel {
private JTable table;
private DefaultTableModel model;
private final Object Column[] = {"id", "titolo", "autore", "prezzo"};
TableData(){
model = new DefaultTableModel();
table = new JTable(model);
model.setColumnIdentifiers(Column);
setLayout(new BorderLayout());
add(new JScrollPane(table), BorderLayout.CENTER);
}
public void updateTable(Object row[]){
model.addRow(row);
}
}
ConnectionDB.java
import java.sql.Statement;
import java.sql.DriverManager;
import java.sql.ResultSet;
public class ConnectionDB {
private String url = "jdbc:mysql://localhost:4444/database_name";
private String user = "root";
private String password = "password";
TableData tableData = new TableData();
//id titolo autore prezzo
public void upload_data(String titolo, String autore, int prezzo){
try{
Connection con = DriverManager.getConnection(url, user, password);
Statement statement = con.createStatement();
String query = "insert into libri(titolo, autore, prezzo)" +
"values ('"+titolo+"','"+autore+"','"+prezzo+"')";
statement.executeUpdate(query);
System.out.println("success");
}
catch(Exception e){
e.printStackTrace();
}
}
public void get_data(){
Object row[] = new Object[4];
try{
Connection conn = DriverManager.getConnection(url, user, password);
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from libri");
while(resultSet.next()){
for(int i = 1; i<=4; i++){
row[i-1] = resultSet.getString(i);
}
tableData.updateTable(row);
}
}
catch(Exception e){
e.printStackTrace();
}
}
}
PanelForm.java
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.jar.JarEntry;
public class PanelForm extends JPanel {
....somebutton.....
ConnectionDB conn = new ConnectionDB();
....some board....
buttonVisualizza.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
conn.get_data();
}
});
}
}
This is my HomePage.java
import javax.swing.text.AbstractDocument;
import java.awt.*;
public class HomePage extends JFrame {
private PanelForm panelForm;
private TableData tableData;
HomePage(){
super("Home");
setSize(800,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocation(200,200);
setLayout(new BorderLayout());
panelForm = new PanelForm();
tableData = new TableData();
add(panelForm, BorderLayout.LINE_START);
add(tableData, BorderLayout.CENTER);
setVisible(true);
}
}
I have already tried to reload the model, and this command: model.fireTableDataChanged();
So immediately, you're creating multiple instances of
TableData....Neither of these two instances have anything to do with each other, so updating one will not update the other.
This suggests that you need to spend some more time researching concepts like
Let's start with, you're using an Object Oriented language, this means, you should be trying to describe your data more as "objects" rather then a lose connection of elements in an array.
Let's start with a "book" concept...
I like
interfaces they free your code from changes which might occur at an implementation level, should you need to shift your data source from say something like a local database to a web API.Having said that, we're still going to need a concrete implement...
I might be tempted to also inject that the records database key into an implementation, but that's details you can address later.
Next, lets take a look at the
ConnectionDB...This is not only inefficient and slow, it's also dangerous.
Create a new instance of the
Connectioneach time is slow and you're leaving yourself open to sql injection attacks. You're also not closing any of the resources, which could mean that the connection will keep them open, degrading the performance of your database.Start by taking a look at The try-with-resources Statement and Using Prepared Statements.
Instead, you should be making use of dependency injection to pass in a reference to the
Connection. This resolves the class of the responsibility of creating the connection, allow you to create what ever connection you need to what ever database you want.You will note that
getDatareturns aListofBooks, this is important, as it removes any implementation details that previously existed. TheConnectionDBdoesn't care how you might use the data, only that when requested, it will return aListof data for you.Also note, I'm not consuming the errors. Error management (beyond cleaning up the resources) isn't this classes responsibility, the caller will want to know when something goes wrong.
Okay, let's move onto the UI by stating with how you would model the data from
ConnectionDBfor the UI.I would, personally, create a custom
TableModelwhich could take aListofBooks and model it as I needed, for example...This is important, because I could use a
ListModelinstead if I wanted to! Same data, different presentation!Now, unless my UI was suitably complex, I might not seperate the table management to a seperate class, instead, I might just do something like...
So, how does this all tie together? Well, maybe something like...