JDK-4404754 : JTableHeader can incorrectly determine its height
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2001-01-15
  • Updated: 2010-05-19
Related Reports
Relates :  
Description

Name: boT120536			Date: 01/15/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Citing report # 108351 as background, I am resubmitting this bug.  I feel the
listed related bugs (4292511 and 4351785) have to do with users not paying close
enough attention to the performance improvements in 1.3, where my submission is
a true bug.

Nutshell: The BasicTableUI code measures height of each custom renderer, as well
as the height reported by the default renderer.  The problem occurs when a
custom renderer precedes the default one -- the default is never asked for its
preferred height.

Please look at this again.

Thanks,

Patrick Forhan.

Original submission follows:---------------------

The following method (from javax.swing.plaf.basic.BasicTableHeaderUI) behaves
incorrectly.  Details follow.

private int getHeaderHeight() {
    int height = 0;
    boolean accomodatedDefault = false;
    TableColumnModel columnModel = header.getColumnModel();
    for(int column = 0; column < columnModel.getColumnCount(); column++) {
        TableColumn aColumn = columnModel.getColumn(column);
        // Configuring the header renderer to calculate its preferred size is
expensive.
        // Optimise this by assuming the default renderer always has the same
height.
        if (aColumn.getHeaderRenderer() != null || !accomodatedDefault) {
            Component comp = getHeaderRenderer(column);
            int rendererHeight = comp.getPreferredSize().height;
            height = Math.max(height, rendererHeight);
            // If the header value is empty (== "") in the
            // first column (and this column is set up
            // to use the default renderer) we will
            // return zero from this routine and the header
            // will disappear altogether. Avoiding the calculation
            // of the preferred size is such a performance win for
            // most applications that we will continue to
            // use this cheaper calculation, handling these
            // issues as `edge cases'.
            if (rendererHeight > 0) {
                accomodatedDefault = true;
            }
        }
    }
    return height;
}

Set-up:
 1.  The first column in the model has a custom renderer.
 2.  All other renderers are default ("null" in each TableColumn)
 3.  The custom renderer has a height that is smaller (shorter) than the height
     of the default renderer. For example, the custom renderer has one line, the
     default renderers have two.

In this case, the UI will calculate the height of the custom renderer, mark the
"accomodatedDefault" flag, and skip all other checks, even though the default
renderer has never truly been "accomodated" (sic, that is, spelled incorrectly).
If the custom renderer is too small, the text presented by the default renderer
will be cut off.

A JTable example is rather large to contrive, and this problem is easily
reproduced.  Suggest modify TableExample3.java from the JFC demos included with
the JDK.
(Review ID: 112853) 
======================================================================

Comments
WORK AROUND Name: boT120536 Date: 01/15/2001 Make sure all custom renderers "in front of" (that are in consecutive order starting at column "0") have heights greater than or equal to the minimum height needed for the default renderer to render properly. Alternately, rather than use the default renderer property, set the header renderer of each column. This loses in performance, though. ======================================================================
25-09-2004