I am trying to populate a JTable with data from a database. I've tried so many different ways and it just doesn't want to work. Currently I have a class which returns a resultset with the entire database to my UIClass which then uses the resultset to populate the JTable. Bellow is my method that retrieves the resultset and then populates the JTable.
private void SetJTable()
{
int count = 0;
String boatclass, senior, under23, junior;
try
{
ResultSet results = object.AllWorldBestTimes();
DefaultTableModel model = (DefaultTableModel) Times.getModel();
model.addColumn("Boat Class");
model.addColumn("Senior");
model.addColumn("Under 23");
model.addColumn("Junior");
while(count<24)
{
boatclass = results.getString(1);
senior = results.getString(2);
under23 = results.getString(3);
junior = results.getString(4);
System.out.println(boatclass + senior + under23 + junior);
model.insertRow(Times.getRowCount(), new Object[]{boatclass, senior, under23, junior});
count++;
}
Times = new JTable(model);
}
catch (SQLException e)
{
System.out.println("Ef");
}
}
Here is the method of retrieving data from the database:
public ResultSet AllWorldBestTimes() throws SQLException
{
DatabaseConnection connection = new DatabaseConnection();
ResultSet result = connection.SelectStatements("SELECT * FROM WorldBestTimes");
return result;
}
there is no crash so i cannot give the stack trace, nor does it go into the catch statement.
any help would be appreciated!
model.insertRow(Times.getRowCount(), ...
Times.getRowCount() is always going to return zero, since it's empty.
Times = new JTable(model);
Reassigns the reference Times, but it doesn't take the old table out of the form or add the new one into the form.
Try this...
model = new DefaultTableModel();
...and this...
model.insertRow(model.getRowCount(), ...
...and this...
Times.setModel(model);
Hard to say if that will do it or not. The code sample isn't exactly SCCE.
Related
I'm trying to filter a JTable but the results are not as expected.
Below is the JTable with the added elements (I'm using MySQL to store the Data)
JTable with contents - Picture
When I try to filter the list for someone specific, I do not get the data from the table. For example, I search for "Ana" and nothing appears.
Search results for "Ana" - Picture
If I try to search using some "numbers", like the salary, I get the right result but the ID is not right. Pictures to clarify the issue below.
Wrong ID
Right ID
The Code to generate the ArrayList with the employees :
public static ArrayList<Angajat> listaAngajati() {
ArrayList<Angajat> listaAngajati = new ArrayList<>();
try (java.sql.Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/angajati", "root", "***");) {
Statement st = conn.createStatement();
st.executeQuery("select * from angajati");
ResultSet rs = st.getResultSet();
Angajat angajat;
while (rs.next()) {
angajat = new Angajat(rs.getInt("id"), rs.getString("nume"), rs.getString("prenume"), rs.getInt("varsta"), rs.getString("adresa"), rs.getDouble("salariu"));
listaAngajati.add(angajat);
}
} catch (SQLException ex) {
System.out.println("Error in database connection: \n" + ex.getMessage());
}
return listaAngajati;
}
public static void arataAngajati() {
ArrayList<Angajat> arataAngajati = listaAngajati();
DefaultTableModel model = (DefaultTableModel) tabelangajati.getModel();
Object[] rand = new Object[6];
for (int i = 0; i < arataAngajati.size(); i++) {
rand[0] = arataAngajati.get(i).getID();
rand[1] = arataAngajati.get(i).getNume();
rand[2] = arataAngajati.get(i).getPrenume();
rand[3] = arataAngajati.get(i).getVarsta();
rand[4] = arataAngajati.get(i).getAdresa();
rand[5] = arataAngajati.get(i).getSalariu();
model.addRow(rand);
}
}
Code to filter the JTable
private void cautaInTabelKeyReleased(java.awt.event.KeyEvent evt) {
DefaultTableModel tabel = (DefaultTableModel) tabelangajati.getModel();
String query = cautaInTabel.getText().toLowerCase();
TableRowSorter<DefaultTableModel> sort = new TableRowSorter<DefaultTableModel>(tabel);
tabelangajati.setRowSorter(sort);
sort.setRowFilter(RowFilter.regexFilter(query));
}
Question : How can I modify the code so when I try to search for a an employee using his name to get the right result (not like now - no results) and when trying to modify the employee data, to get the right ID as shown in the JTable (example in the pictures above) ?
EDIT
In order to filter the data from the table accordingly I had to use
sort.setRowFilter(RowFilter.regexFilter("(?i)" + query));
When I was filtering the table, only the view modified and not the values from the row (Even if I saw the values from the row 3 and values on the backend where from the row 1). I managed to modify the following row and the table works perfectly.
From :
int row = tabelangajati.getSelectedRow();
To :
int row = tabelangajati.convertRowIndexToModel(tabelangajati.getSelectedRow());
I have two classes, the first is the GUI which has jTable, and the other one for querying database.
Adding rows to the table within the same class works fine. I used this way:
((DefaultTableModel) table.getModel()).addRow(values);
While values is a Object[] holding the row content.
This is working fine. But populating has to be done from another class. So I have in the query class:
((DefaultTableModel) rg.table.getModel()).addRow(values);
While rg is an object of the GUI class. And table is public.
This doesn't do anything not even throwing an exception.
What should I change in my query class? Here's my method in the query class:
public void selectPassengers(int rows) {
PreparedStatement pst = null;
ResultSet rs = null;
String query = "SELECT * FROM brs.passenger";
try {
pst = con.prepareStatement(query);
rs = pst.executeQuery();
Object[] attributes = new Object[9];
Register rg = new Register();
while (rs.next()) {
attributes[0] = String.valueOf(rs.getString(1));
attributes[1] = rs.getString(2);
attributes[2] = rs.getString(3);
attributes[3] = rs.getString(4);
attributes[4] = rs.getString(5);
attributes[5] = rs.getString(6);
attributes[6] = rs.getString(7);
attributes[7] = rs.getString(8);
attributes[8] = rs.getString(9);
((DefaultTableModel) rg.table.getModel()).addRow(attributes);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Fetching data from the DB is fine. I could print them to the console.
jTable is I assume is built correctly. I can tell this because I
can insert rows correctly but only within the GUI class itself (the
class where jTable is there).
Moving the inserting logic to a different class (querying class) is
where I am stuck.
I solved this by calling the frame object before the model object.
So instead of rg.model.addRow();, I used rg.frame.model.addRow();, after making frame public in the GUI class.
String[] Titulo = {
"ID",
"CDEP",
"NOMDEP",
"POB"
}; //This is the head of the Jtable
Mnc2 = new DefaultTableModel(null, Titulo);
String[] Filas = new String[4];
try { //HERE IS THE CONECTION TO THE BDD(ACCESS)
Conexion_DDB Conn = new Conexion_DDB();
//Prepared Query
PreparedStatement Consulta = Conn.getConnection().prepareStatement("SELECT * FROM [DEPARTAMENTOS]");
ResultSet Resultadobm = Consulta.executeQuery();
while (Resultadobm.next()) {
//This is the part thath I don't know how to get the Strings or values for each row
Filas[0] = Resultadobm.getString("CDEPID");
Filas[1] = Resultadobm.getString("CDEP");
Filas[2] = Resultadobm.getString("POBDEP");
Filas[3] = Resultadobm.getString("NOMDEP");
//There are more records but just for example
while (Resultadobm.next()) {
//This is the part thath I don't know how to get the Strings or values for the first two rows
Mnc2.addColumn(Filas);//Add the columns
}
/*At this part, I'm trying to get the values equals or higher than 50,000 to show then in the same table at the same time with the two first records found*/
//If you can help me here too I would appreciate it a lot
int Menora = 50000;
if (Mnc2.getValueAt(1, 1).equals(Menora)) {
Tabla_Busquedas.setValueAt(Mnc2, 1, 1);
}
Conn.Desconexion(); //Close the connection
} catch (SQLException ex) {
Logger.getLogger(Form_Tabla.class.getName()).log(Level.SEVERE, null, ex);
}
}
while (Resultadobm.next()) { //This is the part thath I don't know how
to get the Strings or values for the first two rows
I am not sure I understand right.I think you can terminate the loop after you fetched first two rows:
while (Resultadobm.next() && Resultadobm.getRow() <= 2) {
// ...your code
}
You can go to the source:
"SELECT TOP 2 * FROM [DEPARTAMENTOS] ORDER BY [SomeUniqueField]");
I got some problem with a database class, I have got 2 methods there. That supposed to fill JTable with data from database.
The problem is Im reciving errors (tittle). Here is my code:
public class QueryModel {
private Connection connection = null;
private ResultSet resultSet = null;
private Statement statement = null;
private ResultSetMetaData metaData = null;
public void sendStatement(CreateDataBase database,String query)
{
try
{
connection = database.getConnection();
}
catch (SQLException | ClassNotFoundException e)
{
System.err.println(e);
}
if (!query.equals(""))
{
try
{
statement = connection.createStatement();
resultSet = statement.executeQuery(query);
metaData = resultSet.getMetaData();
if (statement.execute(query))
{
System.out.println("Result:");
JTable table = new JTable(buildTableModel());
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
else
{
System.out.println("Executed!");
}
statement.close();
}
catch (SQLException e)
{
System.err.println(e);
}
}
}
public DefaultTableModel buildTableModel() throws SQLException
{
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++)
columnNames.add(metaData.getColumnName(column));
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (resultSet.next())
{
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++)
vector.add(resultSet.getObject(columnIndex));
data.add(vector);
}
return new DefaultTableModel(data, columnNames);
}
}
The problem seems to be getMetaData function in my opinion, without this every query goes smoothly. Problems started when I added this. I haven't been using this yet, so I do not know how to handle this, don't know if there is any sence to trying fixing it instead of doing this other way. Like more manually.
You are implicitly closing the first resultset when you execute the query for the second time in the "if" clause.
I mean, resultset is a pointer to an object defined in the executeQuery() and then you're redefining implicitly the resultset in the execute(query).
That's because you're querying twice.
Try defining metadata from inside your if block and see if it works (probably will)
Leo is right. The MetaData object comes from the first ResultSet which is closed when you re-execute the query. Don't execute the query twice, or if you have to, make sure you get a "fresh" MetaData object from the result set which you are actually navigating.
I have a JTable and I populte the table as follows:
jTable_Std_info.setModel(DBControler.getALLStudents());
And the following is a static method in a class named DBControler which retrieves all the data from the database(Oracle).
public static DefaultTableModel getALLStudents() throws SQLException, Exception {
DefaultTableModel tableModel = new DefaultTableModel();
Vector rows = new Vector();
Vector columns = new Vector();
try {
conn = geConnection();
cst = conn.prepareCall("{? = call std_getInfoFunc}");
cst.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);
cst.execute();
res = (ResultSet) cst.getObject(1);
System.out.print(res);
ResultSetMetaData rsm = res.getMetaData();
for (int i = 1; i <= rsm.getColumnCount(); i++) {
columns.addElement(rsm.getColumnName(i));
}
int row = 0;
while (res.next()) {
Vector vRow = new Vector(); //to store the current row
//System.out.println("Row " +row+"\n");
for (int i = 1; i <= rsm.getColumnCount(); i++) {
String columnValue = res.getString(i);
vRow.addElement(columnValue);
}
row += 1;
rows.addElement(vRow);
}
tableModel.setDataVector(rows, columns);
} catch (SQLException e) {
e.printStackTrace();
} finally {
res.close();
conn.close();
}
return tableModel;
}
So far everything works fine, but the problem is that if I insert a new record in the database, the JTable doesn't get the newly inserted row/data. Why is that and how can I fix this problem?
UPDATE:
It's retrieving the data when I commit my new insertion. So do I have to commit each time I update? Or is there any other ways to do this?
I think that you looking for Oracle Built-In Database Change Notification, not sure if is accesible for Oracle's in free-versions, if not then never mind, for MySQL is there two or three similair API for Java JDBC
But the problem is that if I insert a new record in the database, the JTable doesn't get the newly inserted row/data. Why is that?
The TableModel doesn't know when the database is updated.
and how can I fix this problem?
If your application is adding the row to the database then it also needs to add a row to the TableModel at the same time.