Name: sv35042 Date: 10/18/2002
FULL PRODUCT VERSION :
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)
FULL OPERATING SYSTEM VERSION : SuSE 7.1, Linux 2.2.18, glib
1.2.8, i686
A DESCRIPTION OF THE PROBLEM :
The call to TableColumn.sizeWidthToFit() results in a
NullPointerException thrown by the TableCellRenderer that
renders the column headers. This happens only if the
HeaderRenderer is explicitly set for the TableColumn.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the test program.
EXPECTED VERSUS ACTUAL BEHAVIOR :
I expected that the column would be resized or that at least
nothing would happen, as if the call to sizeWidthToFit()
never happened.
What happens:
The test program will do the following steps:
-Get the first column in the table (col1)
-Print out the value for the header renderer (=null)
-call col1.sizeWidthToFit() (changes nothing, could be left out)
-Set the header renderer of col1 explicitly
-call col1.sizeWidthToFit() (throws NPE)
Obviously the reference to the JTable that is provided to
the method getTableCellRendererComponent of the header
renderer is null. The API of TableColumn does not tell when
or why this can happen.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
first column is: javax.swing.table.TableColumn@e0ff2f
HeaderRenderer is: null
CellRenderer is: null
HeaderRenderer is:
TableColumnTest$MyRenderer[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=null,border=javax.swing.border.EmptyBorder@f99ff5,flags=8,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=,verticalAlignment=CENTER,verticalTextPosition=CENTER]
CellRenderer is:
javax.swing.table.DefaultTableCellRenderer[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=null,border=javax.swing.border.EmptyBorder@f99ff5,flags=8,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,horizontalAlignment=LEADING,horizontalTextPosition=TRAILING,iconTextGap=4,labelFor=,text=,verticalAlignment=CENTER,verticalTextPosition=CENTER]
MyRenderer:getTableCellRendererComponent
table is: null
value is: first Column
is Selected? false
has Focus? false
row false
column false
Exception in thread "main" java.lang.NullPointerException
at
javax.swing.table.DefaultTableCellRenderer.getTableCellRendererComponent(DefaultTableCellRenderer.java:142)
at
TableColumnTest$MyRenderer.getTableCellRendererComponent(TableColumnTest.java:107)
at javax.swing.table.TableColumn.sizeWidthToFit(TableColumn.java:641)
at TableColumnTest.<init>(TableColumnTest.java:55)
at TableColumnTest.main(TableColumnTest.java:71)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
/*
* TableColumnTest.java
*/
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
/**
* $Source$ <br>
* Last modified: $Date$ <br>
* $Revision$ <br>
*
*
* @author chantal
*/
public class TableColumnTest
{
/**
* The main program for the TableColumnTest class
*/
public TableColumnTest()
{
JFrame f = new JFrame( "TableColumnTest" );
f.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
Container content = f.getContentPane();
int rowCount = 9;
int colCount = 5;
Object[] header = new Object[colCount];
Object[][] data = new Object[rowCount][colCount];
for ( int j = 0; j < colCount; j++ )
{
header[j] = "header=" + ( j + 1 );
for ( int i = 0; i < rowCount; i++ )
{
data[i][j] = "row=" + ( i + 1 ) + ";col=" + ( j + 1 );
}
}
JTable table = new JTable( data, header );
TableColumn col = table.getColumn( table.getColumnName( 0 ) );
System.out.println( "first column is: " + col );
System.out.println( "HeaderRenderer is: " + col.getHeaderRenderer() );
System.out.println( "CellRenderer is: " + col.getCellRenderer() );
col.sizeWidthToFit();
col.setHeaderValue( "first Column" );
//col.setHeaderRenderer( new DefaultTableCellRenderer() );
col.setHeaderRenderer( new MyRenderer() );
col.setCellRenderer( new DefaultTableCellRenderer() );
System.out.println( "HeaderRenderer is: " + col.getHeaderRenderer() );
System.out.println( "CellRenderer is: " + col.getCellRenderer() );
col.sizeWidthToFit();
content.add( new JScrollPane( table ), BorderLayout.CENTER );
f.pack();
f.setVisible( true );
}
/**
* The main program for the TableColumnTest class
*
* @param args The command line arguments
*/
public static void main( String[] args )
{
TableColumnTest test = new TableColumnTest();
}
/**
* $Source$ <br>
* Last modified: $Date$ <br>
* $Revision$ <br>
*
*
* @author chantal
*/
private class MyRenderer extends DefaultTableCellRenderer
{
/**
* Gets the tableCellRendererComponent attribute of the MyRenderer object
*
* @param table Description of Parameter
* @param value Description of Parameter
* @param isSelected Description of Parameter
* @param hasFocus Description of Parameter
* @param row Description of Parameter
* @param column Description of Parameter
* @return The tableCellRendererComponent value
*/
public Component getTableCellRendererComponent( JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column )
{
System.out.println( "MyRenderer:getTableCellRendererComponent" );
System.out.println( "\ttable is: " + table );
System.out.println( "\tvalue is: " + value );
System.out.println( "\tis Selected? " + isSelected );
System.out.println( "\thas Focus? " + isSelected );
System.out.println( "\trow " + isSelected );
System.out.println( "\tcolumn " + isSelected );
return super.getTableCellRendererComponent( table, value,
isSelected, hasFocus, row, column );
}
/**
* Gets the preferredSize attribute of the MyRenderer object
*
* @return The preferredSize value
*/
public Dimension getPreferredSize()
{
Dimension dim = super.getPreferredSize();
System.out.println( "MyRenderer:getPreferredSize: " + dim );
return dim;
}
/**
* Gets the minSize attribute of the MyRenderer object
*
* @return The minSize value
*/
public Dimension getMinSize()
{
Dimension dim = super.getMinimumSize();
System.out.println( "MyRenderer:getPreferredSize: " + dim );
return dim;
}
/**
* Gets the maxSize attribute of the MyRenderer object
*
* @return The maxSize value
*/
public Dimension getMaxSize()
{
Dimension dim = super.getMaximumSize();
System.out.println( "MyRenderer:getPreferredSize: " + dim );
return dim;
}
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Don't use this method.
I'm aware that similar bugs exist in the database (all of
older jdk versions, telling the bugs are closed and fixed!).
Some evaluation says it's better anyhow to compute the
column width using all values in the column, not only the
header value. Well, than - declare this method deprecated
(and make it work!) or throw it out.
(Review ID: 153904)
======================================================================