NPE at SubstanceColorUtilities.getInterpolatedRGB()
Closed this issue · 2 comments
I get this exception under Insubstance 7.0:
java.lang.NullPointerException
at org.pushingpixels.substance.internal.utils.SubstanceColorUtilities.getInterpolatedRGB(SubstanceColorUtilities.java:154)
at org.pushingpixels.substance.internal.utils.SubstanceColorUtilities.getInterpolatedColor(SubstanceColorUtilities.java:193)
at org.pushingpixels.substance.internal.utils.SubstanceTextUtilities.getForegroundColor(SubstanceTextUtilities.java:382)
at org.pushingpixels.substance.internal.utils.SubstanceTextUtilities.paintText(SubstanceTextUtilities.java:317)
at org.pushingpixels.substance.internal.ui.SubstanceLabelUI.paint(SubstanceLabelUI.java:179)
at org.pushingpixels.substance.internal.ui.SubstanceLabelUI.__org__pushingpixels__substance__internal__ui__SubstanceLabelUI__update(SubstanceLabelUI.java:198)
at org.pushingpixels.substance.internal.ui.SubstanceLabelUI.update(SubstanceLabelUI.java)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.CellRendererPane.paintComponent(CellRendererPane.java:151)
at javax.swing.plaf.basic.BasicListUI.paintCell(BasicListUI.java:227)
at org.pushingpixels.substance.internal.ui.SubstanceListUI.paintCell(SubstanceListUI.java:579)
at javax.swing.plaf.basic.BasicListUI.paintImpl(BasicListUI.java:317)
at javax.swing.plaf.basic.BasicListUI.paint(BasicListUI.java:240)
at org.pushingpixels.substance.internal.ui.SubstanceListUI.__org__pushingpixels__substance__internal__ui__SubstanceListUI__update(SubstanceListUI.java:788)
at org.pushingpixels.substance.internal.ui.SubstanceListUI.update(SubstanceListUI.java)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JLayeredPane.paint(JLayeredPane.java:585)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5228)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1482)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1413)
at javax.swing.RepaintManager.paint(RepaintManager.java:1206)
at javax.swing.JComponent.paint(JComponent.java:1040)
at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:39)
at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:78)
at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:115)
at java.awt.Container.paint(Container.java:1967)
at java.awt.Window.paint(Window.java:3867)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:781)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:728)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:677)
at javax.swing.RepaintManager.access$700(RepaintManager.java:59)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1621)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:705)
at java.awt.EventQueue.access$000(EventQueue.java:101)
at java.awt.EventQueue$3.run(EventQueue.java:666)
at java.awt.EventQueue$3.run(EventQueue.java:664)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:675)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
When changing the L&F to "Business". This is caused by a JList using the following ListCellRenderer:
public class JListTransparentCells extends DefaultListCellRenderer
{
private static final long serialVersionUID = 1L;
@Override
public Color getBackground()
{
return null;
}
}
A background color of null means that the background color of the parent component should be used (this works with the built-in L&Fs that ship with the JDK).
SubstanceTextUtilities.getForegroundColor() invokes SubstanceColorUtilities.getBackgroundFillColor(component) which returns null.
SubstanceColorUtilities.getInterpolatedColor() expects the second argument to be non-null but it doesn't actually check for it.
I recommend making the following changes:
- SubstanceColorUtilities.getBackgroundFillColor(component) should look at the parent if the component's background color is null.
- SubstanceColorUtilities.getInterpolatedColor() should check for a null argument and throw a clearer NullPointerException indicating that "color2" may not be null.
It is the duty of the component to return the parent background color, not the painting subsystem to derive it. Here's some code from JComponent.java
:
/**
* Gets the background color of this component.
* @return this component's background color; if this component does
* not have a background color,
* the background color of its parent is returned
* @see #setBackground
* @since JDK1.0
*/
public Color getBackground() {
Color background = this.background;
if (background != null) {
return background;
}
Container parent = this.parent;
return (parent != null) ? parent.getBackground() : null;
}
The default list cell renderer also has code to pull out the color of the JList in the getListCellRendererComponent
method. There sounds like there is an entirely differnt problem you are attempting to solve via a hack with the background color, as this feels to me to be the wrong solution.
Shemnon,
Good catch! Thank you.