Reputation: 7
I am working with swing JTable
and have a trouble with repainting table. I draw a JTable
with thr following code
Object[] column = new Object[]{"Entity", "Attribute"};
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}};
TableCellRenderer cellRenderer = new TableCellRenderer();
JTable table = new JTable(new DefaultTableModel(rowData, column));
table.setCellSelectionEnabled(true);
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
Below is my table renderer code ..
public class TableCellRenderer implements javax.swing.table.TableCellRenderer {
//private JPanel panel;
JTextField field;
private JTable table;
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
boolean isSelected, boolean hasFocus, final int row, final int column) {
this.table = table;
//JTextField field = null;
System.out.println("Rendere : Row : " + row + "Column : " + column);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JButton button = new JButton("?");
button.setPreferredSize(new Dimension(20, panel.getHeight()));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SelectionDialog(panel, table, value, row, column);
}
});
if(table.getValueAt(row, column) != null){
field = new JTextField(table.getValueAt(row, column).toString());
}else{
field = new JTextField(table.getValueAt(row, column).toString());
}
field.setPreferredSize(new Dimension(30, panel.getHeight()));
panel.add(field, BorderLayout.WEST);
panel.add(button, BorderLayout.EAST);
return panel;
}
this is how i am updating contents of a cell in table..
SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);
I am updating the table model data via the SelectionDialog
for e.g change data at row 0, colum 0 to E7 etc. After changing data in table model i have tried the following options but none of them has refreshed the table data in view however the data in model of JTable
was updated correctly. If I add a new row on the fly and then call the below methods then every thing work fine but if I modify data in the model of an existing row then none of the solution mentioned below is working
//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"});
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column);
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel()));
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged();
//SelectionDialog.this.table.repaint();
// SelectionDialog.this.table.revalidate();
Please provide any insights about the problem as I am to swing and may have missed some very prominent things.
Edit 1: Just adding one more note which i wanted to place earlier but don't know how i missed. Table is not updated in general but if i focus out from the cell in which change was made or i change the size of table then it immediately change the contents of that particular cell to fresh selected value.
Problem Solved:
I am placing my findings for someone who is facing similar problem.
I rendered a button and a text box inside each cell in my table. When button was clicked (Editor code is not provided as it looks irrelevant to me to place here) a dialog appear which inputs value from user and update the specific column and row. The lines i mentioned as not working at the end of my post (before edit 1) were working correctly however renderer was not executing unless i manually focus out from the selected cell (whose button was clicked) or manually change the size of jtable which make sense as button was inside editor and button click shows that cell is edited and off-course renderer will not execute unless editing is finished which requires focus out or enter key etc. I applied the following code as
table.editCellAt(-1, -1);
It focus out from the edited cell (edited with the button) and hence renderer executes and work as expected.
Upvotes: 0
Views: 1412
Reputation: 36611
When you are using a DefaultTableModel
and you want to update a certain value, you need to use the DefaultTableModel#setValueAt
method.
Calling this method (on the Event Dispatch Thread of course) will update your model and fire the necessary events. Those events will cause your JTable
to update itself.
A few additional remarks about your renderer:
JButton
to your table in the renderer has no effect, unless you have an editor as well. The button will not be clickable, and the action listener you attach to it will never be called. See the renderers and editors section in the JTable
tutorial for more information.getValueAt
in your renderer. The value is passed in as one of the arguments Upvotes: 2