JDK-6888157 : NullPointerException in BasicProgressBarUI updateSizes
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6u14
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-10-05
  • Updated: 2011-02-16
  • Resolved: 2010-05-21
Description
FULL PRODUCT VERSION :
1.6.0_14

A DESCRIPTION OF THE PROBLEM :
updateSizes() assumes componentInnards is not null (see comment line 465, it says only call after sizeChanged()).  sizeChanged() returns true if componentInnards is null without initializing the object (see line 949).

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run attached test case, wait for error to occur.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at javax.swing.plaf.basic.BasicProgressBarUI.updateSizes(BasicProgressBarUI.java:471)
	at javax.swing.plaf.basic.BasicProgressBarUI.getBox(BasicProgressBarUI.java:428)
	at com.sun.java.swing.plaf.windows.WindowsProgressBarUI.getBox(WindowsProgressBarUI.java:225)
	at javax.swing.plaf.basic.BasicProgressBarUI.paintString(BasicProgressBarUI.java:696)
	at javax.swing.plaf.basic.BasicProgressBarUI.paintDeterminate(BasicProgressBarUI.java:683)
	at com.sun.java.swing.plaf.windows.WindowsProgressBarUI.paintDeterminate(WindowsProgressBarUI.java:180)
	at javax.swing.plaf.basic.BasicProgressBarUI.paint(BasicProgressBarUI.java:395)
	at javax.swing.plaf.ComponentUI.update(ComponentUI.java:143)
	at javax.swing.JComponent.paintComponent(JComponent.java:763)
	at javax.swing.JComponent.paint(JComponent.java:1029)
	at javax.swing.JComponent.paintToOffscreen(JComponent.java:5124)
	at javax.swing.BufferStrategyPaintManager.paint(BufferStrategyPaintManager.java:278)
	at javax.swing.RepaintManager.paint(RepaintManager.java:1220)
	at javax.swing.JComponent._paintImmediately(JComponent.java:5072)
	at javax.swing.JComponent.paintImmediately(JComponent.java:4882)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:803)
	at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:714)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(RepaintManager.java:694)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueUtilities.java:128)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.awt.FlowLayout;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.UIManager;


public class ProgressNPETest {

  public static void main(String[] args) {
    try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    }
    catch(Exception e) {
    }
    JFrame frame = new JFrame();
    frame.getRootPane().setLayout(new FlowLayout());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JProgressBar progressBar = new JProgressBar(0, 0);
    progressBar.setStringPainted(true);
    frame.getRootPane().add(progressBar);
    frame.setSize(200, 200);
    frame.setVisible(true);
    ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);
    executor.scheduleWithFixedDelay(new Job(progressBar), 1, 5, TimeUnit.SECONDS);
  }

  private static class Job implements Runnable {
    private JProgressBar progressBar;
    public Job(JProgressBar bar) {
      progressBar = bar;
    }
    public void run() {
      try {
        progressBar.setIndeterminate(true);
        progressBar.setString("1");
        Thread.sleep(5000);
        progressBar.setIndeterminate(false);
        for(int i = 0; i < 1000; i++) {
          progressBar.setMaximum(1000);
          progressBar.setValue(i);
        }
        progressBar.setIndeterminate(true);
        progressBar.setString("2");
        Thread.sleep(5000);
        progressBar.setIndeterminate(false);
        for(int i = 0; i < 1000; i++) {
          progressBar.setMaximum(1000);
          progressBar.setValue(i);
        }
        progressBar.setValue(0);
        progressBar.setString("");
      }
      catch(InterruptedException e) {
        
      }
    }
  }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Doesn't cause a problem that I can find, just clutters the console with NPE.

Comments
PUBLIC COMMENTS The problem is in the test. You should use something like "SwingUtilities.invokeAndWait" whenever you access to the SWING components. I've done that and your test didn't throw NPE.
21-05-2010