I'm having a hard time with a JTable
data refreshing.
I'm implementing my own TableModel
, extending from javax.swing.table.AbstractTableModel
, with a method that receives an java.util.ArrayList<>
and process it to build an Object[][]
from where the table data is read.
The logic is as following:
I'm implementing a JList with some record keys, when the user selects one, a method is fired that picks up the key and queries a MySQL database to fetch records related with that key. The final result is an ArrayList<> that I passed to the TableModel to construct the data and then set it to my table.
It works normally but after a few hits, it stops displaying the table data, and after a little time, it starts working again. I'm not sure if I'm having problem refreshing the table or the entire GUI.
This is a excerpt of the code:
Method for build the data of the table:
public void createTableData(java.util.ArrayList<Lote> alLote) {
//Lote is an entity class modeling the database table.
TABLE_DATA = new Object[alLote.size()][TABLE_COLUMNS.length];
//TABLE_DATA is an Object array, TABLE_COLUMNS is a String[] containing the names of the columns.
int i = 0;
for (Lote element : alLote) {
int j = 0;
TABLE_DATA[i][j++] = element.getFirstColumnValue();
//and so son
i++;
}
super.fireTableDataChanged();
}
When launching the GUI, it starts with an empty ArrayList<>:
LoteTableModel ltm = new LoteTableModel();
arrayList = new ArrayList<Lote>();
ltm.createTableData(arrayList);
myTable = new JTable();
myTable.setModel(ltm);
scrollPane = new JScrollPane(myTable);
I'm using DesignGridLayout btw, a RowGroup which hides when the table has no records and shows when it has results, and a JScrollPane as table container.
dgl = new DesignGridLayout(panel);
dgl.row().center().group(group).add(scrollPaneContainingTable).fill();
centerPanel.add(panel, BorderLayout.CENTER);
getContentPane().add(centerPanel);
centerPanel.setVisible(true);
Then, everytime the user selects an item from a JList, I query the database and fetch records related to the selected value:
public void listSelectionChanged() {
bloque = alBloque.get(listBloque.getSelectedIndex());
//bloque is another entity, alBloque is an ArrayList<Bloque> from which the JList (named listBloque) ListModel is constructed.
try {
//database query here, omitted
if (result.getStatus() == SUCCESS) {
//the query returned a populated ArrayList<Lote>
alLote = result.getArray();
((LoteTableModel) myTable.getModel()).createTableData(alLote);
myTable.revalidate();
}
} catch (Exception e) {}
}
As I stated before, it works fine a couple of times, clicking the values on the list displays their related records on the table, but then after clicking several ones, it stops displaying data at all. Leaving it for a moment and then clicking on some value again, will display the correct data again, so as I told before, I'm not sure if is more like a GUI refreshing issue.
Any help will be greatly appreciated.
I've found the issue, and as I thought, it was a GUI issue, not of refreshing, but of misuse of the Layout package :)
As I stated, I'm using DesignGridLayout
, it has the benefit of creating a group of rows, called RowGroup
and hide it or show it according to the GUI convenience/need.
I placed the table in a RowGroup
and call the show()
method when there were results on the database, and the table was loaded with these results,thus displaying it; I called the hide()
method when no results were found and therefore, the table will be empty, so I hide it.
The point is that calling the hide()
method is cumulative... If I called the method 3 times, I would need to call the show() method 3 times too in order to show it, so, if I choose 3 consecutive rows in my JList
with empty result sets for the table, I will be calling the hide()
method 3 times, so when I choose a row that indeed had results for the table, I will be calling the show()
method just once, so the table never displayed as expected until 3 attempts at selecting rows with results for the table.
I have put a control field which forces the app to call the hide()
method just once, because sadly, the DesignGridLayout
package doesn't include an isHide()
method to test if hide()
has been called.
Thank you very much for your support. My mystery question is now solved.