Customizing Table Editing and Display
A table's data lives in a table model, and methods such as setValueAt, removeRow, and addRow change that data; the view updates automatically.
Where a Table's Data Really Lives
Before any theory, consider a small question. A table on screen shows rows and columns of values, and a user can click a cell and type into it. When that happens, what decides whether the typed text is accepted, displayed as a check box, or shown as plain text? The answer comes from a piece of Java that sits behind the table, not from the table's appearance.
Take a moment to make a guess. If a learner typed text into a cell in column 1, what would you expect the table to do? Keep your guess in mind. The rest of this article follows the mechanism that produces the answer, one state change at a time.
The Table Model Holds the Data
A JTable does not own the data it displays. The data lives in a table model, and the DefaultTableModel class is the standard model that provides methods for changing it. The JTable is the visible view of that model. Three DefaultTableModel methods do most of the work: setValueAt, removeRow, and addRow.
The important point is where you make the change. You call these methods on the model, not on the visible table. The source states that when you modify the model, the view is automatically updated to reflect the changes. You never write separate code to redraw the table after an edit.
Changing One Cell with setValueAt
The setValueAt method takes an item together with a row number and a column number, and it replaces the item in that one cell. Only the targeted cell changes. The other cells in the same row and the other rows are left as they were.
Setting a cell to null is a special case. The source says that if the item in a given cell is set to null, that cell will be empty. Empty is not the same as deleted. The row still exists, and only the value in that one cell is cleared.
Adding and Removing Whole Rows
The addRow method takes an array of items and appends a new row at the end of the table, filling the cells with the items in that array. The removeRow method takes a row number and deletes that entire row. Because removeRow deletes the whole row, the rows below it move up to fill the gap.
The diagram above is a generated example that uses three names. Ben was at index 1 and Chloe at index 2. After removeRow(1), Ben is gone and Chloe is at index 1. Any code that refers to row numbers after a removal must account for this shift, because the same index now points to different data.
Empty Cells Versus Removed Rows
How getColumnClass Chooses Behavior
The table does not guess what kind of data a column holds by looking at the cells. Instead, it calls getColumnClass for each column and uses the returned class to decide how to display and edit that column's items. The decision therefore depends entirely on what the method returns for that column number. The table asks the question, and the return value is the answer it acts on.
The source documents two behaviors that follow from the returned class. First, if a column is specified to hold Boolean values, its cells are displayed and edited as check boxes. Second, for numeric types, the table will not accept illegal input when the user types a value. The source gives these two as examples and does not list every possible class and its appearance, so treat these two as the documented cases.
A Table Model That Declares Column Classes
getColumnClassis overridden so the table can ask which class each column holds- Column 1 returns
Boolean.class, so its cells are shown as check boxes - Column 2 returns
Integer.class, so numeric entry is checked setValueAtreplaces only the cell at row 0, column 0setValueAtwith null leaves row 0, column 2 empty while the row remainsaddRowappends Chloe at the end of the modelremoveRow(0)deletes the whole first row, so the remaining rows shift up- The
JTableis created from the model and reflects these changes automatically
How a Change Travels from Model to Screen
Follow one change through the system. Your code calls a method on the model, such as setValueAt, addRow, or removeRow. The model's data changes. The JTable, which displays that model, reflects the change. The source says the view is updated automatically, so the path from model to screen requires no extra redraw code from you.
Customizing Editors and Renderers
The column class is not the only way to change behavior. The source notes that it is possible to change the way a table edits or displays items, and it points to two methods in the JTable class: setDefaultEditor and setDefaultRenderer. The source names these methods and says they exist. It does not show their full signatures or code, so this article does not describe their parameters or usage beyond that.
Tracing a Result That Looks Wrong
When a table behaves differently from what you expected, work through three checks in a fixed order. This order follows the path the data takes, so you can locate the point where the result diverged.
- 1Check the model: did the
setValueAt,removeRow, oraddRowcall change the data you thought it changed? - 2Check the column class: what does
getColumnClassreturn for the column that misbehaves? - 3Check JTable customization: has the table's default editor or renderer been customized with
setDefaultEditororsetDefaultRenderer?
Applying this order to the opening question: if a learner typed text into column 1 and that column's class is Boolean, the displayed cell is a check box, so the typed text does not appear as ordinary text. Reaching that conclusion requires checking the column class first, then the customization second.
Mistakes Beginners Make with Tables
Common mistake Editing the visible table and expecting the model to change
What it looks likeChanging a value through the view while assuming the model's stored data was updated
Why it failsThe
JTabledoes not own the data. The data lives in the table model, and the model is where changes belong.Do this insteadCall setValueAt, addRow, or removeRow on the DefaultTableModel.
Common mistake Writing code to redraw the table after every model change
Why it failsThe source states that the view is automatically updated when the model is modified.
Do this insteadChange the model and let the JTable reflect the change.
Common mistake Treating a null cell as a deleted row
What it looks likeCalling setValueAt with null on a cell and expecting the row to disappear
Why it failsSetting a cell to null only empties that cell. The row still exists.
Do this insteadUse removeRow when the whole row should be taken out of the table.
Common mistake Using an old row number after removing a row
What it looks likeCalling removeRow(1) and then acting on the row that was at index 2 as if it had not moved
Why it failsRows below a removed row move up, so the same index now refers to different data.
Do this insteadRecheck which data sits at each index after any removeRow or addRow call.
Common mistake Assuming the cell type is determined by the value in the cell rather than by getColumnClass
Practice Tracing a Table
A DefaultTableModel starts with three rows: Ana, Ben, and Chloe, in that order. Predict the state of the table after these calls: setValueAt(null, 1, 0) and then removeRow(0). Write down which name, if any, appears at each row index, and say whether any cell is merely empty. Then check your answer against the model-column-customization order from the previous section.
Hints
setValueAtwith null only empties one cell, so the row count does not change at that stepremoveRow(0)deletes the whole first row, and the remaining rows move up- Ask yourself which index holds which data after each call
Key Takeaways
- A
JTabledisplays data held by a table model, and changes made throughDefaultTableModelmethods such assetValueAt,addRow, andremoveRowupdate the view automatically. setValueAtreplaces one cell, setting a cell to null leaves it empty,removeRowdeletes a whole row, andaddRowappends a new row at the end.- The table calls
getColumnClassfor each column and uses the returned class to decide how items are displayed and edited, such as Boolean columns shown as check boxes and numeric columns rejecting illegal input. - When a result looks wrong, check the model first, then the column class, then whether the
JTable's default editor or renderer has been customized withsetDefaultEditororsetDefaultRenderer.