Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4382860
Votes 0
Synopsis DefaultTableCellRenderer has new optimisation that make it difficult to subclass
Category java:classes_swing
Reported Against 1.3
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs
Submit Date 25-OCT-2000
Description




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)

If you wish to change the background color for a cell dependent on value,
selection, table, focus etc. Then overriding setValue() in
DefaultTableCellRenderer has not got the parameters you require.

So, override getTableCellRendererComponent instead :) !

The following code seems reasonable :-

Component ret = super.getTableCellRendererComponent(table,value, isSelected,
hasFocus, row, column );

if( ((Integer)value).intValue() == 0 ){
    ret.setForeground( Color.yellow );
    ret.setBackground( Color.red );
}else {
    if( isSelected ){
        ret.setBackground(table.getSelectionBackground());
        ret.setForeground(table.getSelectionForeground());
    }
    else{
        ret.setBackground(table.getBackground());
        ret.setForeground(table.getForeground());
    }
}
return ret;

This works fine 1.1.8 to 1.2.2, trouble is, the new optimisation in 1.3 calls
setOpaque( false ) in getTableCellRendererComponent, based on the current
colors, which you were just about to change!

The result is VERY confusing and took me hours to find!
(Review ID: 110756) 
======================================================================




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)

DefaultTableCellRenderer has a new, undocumented optimization that is confusing
developers. The getTableCellRendererComponent() method will avoid painting the
cell background by setting opaque to false if the cell background matches the
table background. While this speeds up painting, it is confusing to subclassers
because they don't know that this is happening.

Here is the optimization, taken from the code for DefaultTableCellRender.java:

// ---- begin optimization to avoid painting background ----
Color back = getBackground();
boolean colorMatch = (back != null) && ( back.equals(table.getBackground()) ) &&
table.isOpaque();
setOpaque(!colorMatch);
// ---- end optimization to aviod painting background ----

Subclassers often override this class to specify a background color, then get
confused because it doesn't paint properly. To see why, read the comments to bug
4336152.

The documentation for this method needs to describe this optimization.
(Review ID: 109220)
======================================================================
Work Around




I just added setOpaque( true ) before returning.
======================================================================




Several workarounds are described in the comments to 4336152.
(Review ID: 109220)
======================================================================
Evaluation
Fixed in 1.4 beta. The optimisation has not been removed, we 
just override isOpaque() now instead of calling setOpaque(). 

  xxxxx@xxxxx   2001-01-03
Comments
  
  Include a link with my name & email   

Submitted On 08-JAN-2001
MiguelM
Good work! I like that fix.


Submitted On 12-JAN-2001
teague
I have not seen the isOpaque() "fix."
However, as a user of the DefaultTableCellRenderer I fully expect to be able to set the background color of 
my cell. This worked in 1.2.2 and now does not work in 1.3.
Will this "fix" allow setBackground() or will I have to override isOpaque() as well?
Will I be able to call setOpaque(), or will your "fix" prevent that?

JDK bug 4336152 says "this is not a bug", but obviously it broke a lot of applications that previously worked 
in 1.2.2. I hope the 1.4 fix is not another step backwards.


Submitted On 16-JAN-2001
MiguelM
teague: Although I haven't seen the fix, I suspect that
isOpaque() will look something like this:

public boolean isOpaque()
{
  // tableBg needs to be set to table.getBackground()
  // in the method getTableCellRendererComponent().
  return !tableBg.equals(getBackground());
}

This works fine for me. Try it. You'll see that you can use
setBackground() without any problems.



PLEASE NOTE: JDK6 is formerly known as Project Mustang