Concepts / Column Class and Display

Column Class 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.

  • Programming

A Table Edit Starts Somewhere Other Than the Table

Suppose a program shows a grid of student names and scores, and a user types a new score into one cell. Where does that new score go, and who is responsible for redrawing the grid? Many beginners expect to find code that edits the visible table. The source material for this topic shows that the answer is different: the table does not own the data it displays.

What do you think happens?

If a column is declared to hold Boolean values, how do you expect its cells to look and behave?

  • As plain text that cannot be changed

  • As check boxes that can be ticked and unticked

  • As numbers that reject letters

Reveal answer
Answer:

As check boxes that can be ticked and unticked

The source states that a column specified to hold Boolean values is displayed and edited as check boxes. The mechanism that makes this happen is the column class, which the rest of this article traces step by step.

Where the Data Actually Lives

A JTable is the visible component. It does not own the data it displays. The data lives in a table model, and DefaultTableModel is the standard model that provides methods for changing it. Think of the model as the single store of truth and the JTable as a view that reads from that store.

Three DefaultTableModel methods do most of the work. setValueAt takes an item along with a row number and a column number, and it replaces the item in that one cell. removeRow takes a row number and deletes that row. addRow takes an array of items and appends a new row at the end of the table, filling its cells with those items.

Following an Edit from Model to Screen

The important point is where you make the change. You call setValueAt, addRow, or removeRow on the model, never on the visible table. The source states that when the model is modified, the view is automatically updated to reflect the change. You do not write separate code to redraw the table after an edit. The model is the one place where data changes, and the view follows it.

Your codecalls a model methodDefaultTableModelstores the dataJTabledisplays the new valuesetValueAt, addRow, or removeRowview updates automatically
After a change is made on the model, how does the new value reach what the JTable shows?

Clearing a Cell Versus Deleting a Row

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 becomes empty. Empty is not the same as deleted: the row still exists, and only the value in that one cell is cleared. Removing a row with removeRow takes the whole row out of the table. The short trace below uses a model that already has two columns named Name and Score, and it follows each change through the model.

Code walkthrough
model.addRow(new Object[]{"Ann", 90});
model.addRow(new Object[]{"Ben", 75});
model.setValueAt(82, 1, 1);
model.setValueAt(null, 0, 1);
model.removeRow(0);
  1. 1
    Line 1 adds a row whose cells hold Ann and 90. The row is placed at the end of the model.
  2. 2
    Line 2 adds a second row for Ben and 75 beneath Ann.
  3. 3
    Line 3 changes only one cell: row 1, column 1, which is Ben's score. Ben's name is untouched.
  4. 4
    Line 4 sets Ann's score cell to null. The cell is empty, and Ann still occupies row 0.
  5. 5
    Line 5 removes the entire row at index 0. Ann and her empty score both disappear from the table.
  • addRow appends Ann to the end of the table at row 0
  • addRow appends Ben below Ann at row 1
  • setValueAt replaces the item in row 1, column 1, so Ben's score becomes 82
  • setValueAt with null leaves Ann's score cell empty; Ann's row still exists
  • removeRow(0) deletes Ann's entire row, not just her score

Row Positions After a Removal

When you remove a row from the middle of the model, the rows below it do not keep their old positions. The source describes removeRow as deleting a row, and it describes the model as the source of what the view shows. A consequence follows from that: each row below the deleted one moves up by one index, so the view's row position for a given item is always the model's current row position. This is a reasoning step drawn from the described behavior, not a separate rule the source spells out.

Annrow 0Annrow 0Benrow 1, removedCararow 1, moved upCararow 2Devrow 2, moved upDevrow 3
When Ben's row is removed from the middle of the model, which rows change their index?

How getColumnClass Chooses Display and Editing

The table does not guess what kind of data a column holds by looking at its cells. For each column, it calls getColumnClass and uses the class that the method returns 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. If you want to know why a column looks or behaves a certain way, the return value of getColumnClass for that column is the place to look.

Column numberone column at a timegetColumnClasscalled for that columnReturned classdecides the behaviorBoolean classcells shown as check boxesNumeric classillegal input not acceptedOther classesbehavior not detailed insourcetable asksreturns a classBooleannumericany other
Given the class returned for a column, which display and editing behavior does the JTable apply to its cells?

The source gives two documented consequences of the returned class. First, a column specified to hold Boolean values has its cells 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 presents these two as examples and does not list every class and its appearance, so treat these two as the documented cases.

What do you think happens?

A column's getColumnClass returns a numeric class. A user types letters into one of its cells. What does the table do?

  • It accepts the letters and stores them

  • It refuses the illegal input

  • It converts the letters to zero

Reveal answer
Answer:

It refuses the illegal input

The source states that for numeric types the table will not accept illegal input when the user types a value. The check happens because of the class that getColumnClass returned for that column.

Customizing Editors and Renderers

Mistakes Learners Make with Table Edits

  • Common mistake

    Trying to change what the table shows by editing the JTable itself

    Why it fails

    The source states that the data lives in the table model and that the view updates automatically when the model changes.

    Do this instead

    Call setValueAt, addRow, or removeRow on the DefaultTableModel and let the view follow.

  • Common mistake

    Assuming setting a cell to null deletes the row

    What it looks like

    setValueAt(null, 0, 1) leaves row 0 in place with an empty cell.

    Why it fails

    The source says a null cell is empty, and the row still exists. Only removeRow takes a whole row out.

    Do this instead

    Use removeRow(row) when the entire row should disappear.

  • Common mistake

    Expecting the table to infer a column's type from the values in its cells

    Why it fails

    The source says the table calls getColumnClass for each column and uses the returned class, not the cell contents.

    Do this instead

    Check what getColumnClass returns for that column number.

  • Common mistake

    Assuming row numbers stay fixed after a deletion

    What it looks like

    After removeRow(1) on a four-row model, the item formerly at row 2 is at row 1.

    Why it fails

    Removing a row takes it out of the model, so the remaining rows below it are at new positions.

    Do this instead

    Read row positions from the model's current state rather than from earlier notes.

Diagnosing a Wrong Table Result

When a table behaves differently from what you expected, work through three checks in the order below. This order follows the path the data takes, so each check either locates the problem or rules out a layer.

  1. 1
    Check the model: did the setValueAt, removeRow, or addRow call change the data you thought it changed?
  2. 2
    Check the column class: what does getColumnClass return for the column that misbehaves?
  3. 3
    Check customization: has the JTable's default editor or renderer been changed through setDefaultEditor or setDefaultRenderer?
MEDIUM

A table's Score column shows a check box in every row, but you expected a number. Using the three checks in order, describe what you would verify first and what each check would rule in or out.

Hints
  • Start with the model. Is the stored value in the Score column what you intended?
  • Next, look at what getColumnClass returns for the Score column number.
  • Only after the first two checks should you consider whether a default renderer or editor was customized.

Key Takeaways

  • A JTable does not own its data; a DefaultTableModel holds it, and you change the table by calling setValueAt, removeRow, or addRow on the model, after which the view updates automatically.
  • setValueAt replaces one cell, setting a cell to null leaves it empty, removeRow deletes a whole row, and addRow appends a new row at the end.
  • The table calls getColumnClass for each column and uses the returned class to decide display and editing; Boolean columns become check boxes, and numeric columns refuse illegal input.
  • When results diverge, check the model first, then the column class returned by getColumnClass, then whether setDefaultEditor or setDefaultRenderer has been customized.