JavaSwingJTable and TableModelColumn headers: JTable vs. JTableHeader


JTable vs. JTableHeader

Some code analysis (rather technical)

Use of its JTable by JTableHeader

Use of its JTableHeader by JTable

Column models

The header has a column model of its own. It can be set on construction or later.

It will be overridden if the header is associated to a JTable and that table's column model is exchanged. It will not be overridden when the header is assigned a JTable (neither in header's setTable nor in table's setTableHeader).

If the header has a different column model than its table, resizing/dragging causes confusion, especially if the dragged/resized column is not part of the table's column model (and TableColumns probably shouldn't be in multiple column models).

Standalone tables

Even if you set the table's header property to null, the table will install it as the column-header-view of the scroll pane it is contained in (i.e. remove a component that is there). See below.

Standalone table headers

A JTableHeader displays the header values of a TableColumnModel.

It takes the explicit widths from the column model, while its preferred size uses the preferred widths (though without resizing, usually the sum of these widths is the same, therefore it does not matter; but it its minimum/maximum width will be weird - but in a viewport it does not matter).

It uses implicit heights (maximum of preferred heights modulo broken optimizations).

Its should be made Scrollable with (at least) a proper preferredScrollableViewSize (width).

It does allows reordering of the items (one at a time) and resizing at one side (that puts its preferred width out of synch). It does not allow any keyboard navigation nor selection of items (it does not even get the focus).

It might suggest itself as a substitute for essentially missing horizontal JList (whose horizontal-wrap mode gives each item equal width and has a broken Scrollable implementation).

Besides some adjustments, the data must be wrapped in an otherwise superfluous TableColumnModel, and either one uses a bogus JTable around (more memory overhead) or the renderer's aren't given context (JTable argument).

One could as well start from scratch and do it in a generic way, or use JTable which has more features.

Other headers

One can always keep the JTableHeader around as to make JTable have access to the resizing/dragged column, but one need not show it. (As dragging painting is implemented in the TableUI, there is little one can do about it).

Using JTable as header

This may be handy because it allows editing (though it is not clear how that interferes with dragging/resizing).

A first step is to disable the column layout because that should be done by the main table. But this table with fixed column widths is not exactly what is needed: Because the main table will layout the columns based on their preferred widths (and the auto-resize-mode), the header's preferred (and other) widths also should be calculated that way.

Therefore, treat this as a side-product and disable the preferred etc. size methods again. This produces a table that does not work alone, but needs another one for column layout.

Now, if column resizing is needed, the main table either needs a JTableHeader (that is not displayed) to find the resized column, or some layout code has to be rewritten.Similarly, if column dragging is desired, the main table (TableUI) needs a JTableHeader (that is not displayed) to find the dragged column/distance. Therefore, there is a need for a feature to disable installing the table header.

For a start, I ended up with this attempt. There are still some issues: The header table has a separate JTableHeader, how TableColumnModels are synchronized is not clear; and the header table still looks like a table.


(C) 2001-2009 Christian Kaufhold (swing@chka.de)