So i am working with a JTable
, It has Columns A-K. with A and B being the only editable ones. If someone edits an empty row in A, I make an API call to get B then i make a DB call to get all rows where B exists.If someone edits an empty row in B, i make the same call as the will be retrieved from the DB for that row as well. The call returns 0-N rows. If 0 rows were returned, I change the values of all row except B to N/A otherwise i populate the rows using the data.Once populated, i make all columns non-editable. The DB call occurs in its own thread as once the call is return i create my own record object which I add to the tablemodel.
I have my own TableModel
and a TableModelListener
to keep the data and handle changes in values.
Here is my issue. I am using TableCellRenderer
and using the cellrenderer to see if the value was changed, if so then i make the calls and populate as needed. When a large number of rows is being pulled from DB, it takes a while to load and making all that records so I tried to use a ProgressBar
to show the user that the screen isn't just frozen, it is progressing and by how much. However the frame that comes up is blank and nothing gets displayed. I get the feeling i am doing something either improperly or missing something.Any help much appreciated.
some code to understand what i am talking about
public class MyPanel extends JPanel {
private JTable myTable;
private MyTableModel tm;
//OTHER FIELDS
public static void createPanel() {
tm = new MyTableModel(columnnames);
myTable = new JTable(tm);
TableColumn account = myTable.getColumnModel().getColumn(
MyTableModel.ACCOUNT_INDEX);
account.setCellRenderer(new MyTableRenderer(
MyTableModel.ACCOUNT_INDEX));
}
}
public class MyTableRenderer extends DefaultTableCellRenderer{
protected int interactiveColumn;
public MyTableRenderer(int interactiveColumn) {
this.interactiveColumn = interactiveColumn;
}
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
Component c = super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
if (column == interactiveColumn && hasFocus) {
//DO DB and API CALLS HERE
//IF DB CALL DISPLAY A NEW FRAME WITH PROGRESSBAR
}
return c;
}
}
Sorry for formatting issues
Use SwingWorker
, which allows you to update your TableModel
as you examine your result set.
Addendum: Don't try to update the TableModel
from the renderer. You can update the model when your implementation of CellEditor
has concluded, by starting a suitable worker in getCellEditorValue()
. In that way, the revised data will be available when the renderer is next invoked for any modified cell(s). This related example outlines the approach.
Addendum: getCellEditorValue()
is invoked after editing has concluded, but starting the worker in setValueAt()
offers more reliable access to the target row and column.