JDK-4532632 : REGRESSION: NullPointerException in javax.swing.text.FlowView.layout()
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.4.0
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: generic
  • CPU: generic
  • Submitted: 2001-11-29
  • Updated: 2001-11-30
  • Resolved: 2001-11-30
Related Reports
Relates :  
Description
On both Solaris 8 and Windows 2000 with JDK 1.4 beta 3, the following code results in a NullPointerException in javax.swing.text.FlowView.layout.  This code works fine on both platforms with JDK 1.3.1.


Code:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;

public class Frame1 extends JFrame
{
    JPanel contentPane;
    BorderLayout borderLayout1 = new BorderLayout();
    JScrollPane jScrollPane1 = new JScrollPane();
     
     /**Construct the frame*/
    public Frame1()
    {
        enableEvents(AWTEvent.WINDOW_EVENT_MASK);
        try
        {
            jbInit();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
     
    /**Component initialization*/
    private void jbInit() throws Exception
    {
        contentPane = (JPanel) this.getContentPane();
        this.setSize(new Dimension(600, 400));

        /* Create the editor kit and document */
        JTextPane jTextPane1 = new JTextPane();
        jTextPane1.setContentType("text/html");
        HTMLEditorKit editorKit =
            (HTMLEditorKit)jTextPane1.getEditorKit();

        /* Set up the text pane */
        HTMLDocument doc = (HTMLDocument) jTextPane1.getStyledDocument();
        final StyleSheet style = doc.getStyleSheet();
        
        // Commenting out this line prevents the NullPointerException
        style.addRule(
            "td { color : #00FF00; font-family: Arial; font-size: 18pt; }");

        HTMLDocument newdoc = new HTMLDocument(style);
        newdoc.setParser(new
        javax.swing.text.html.parser.ParserDelegator());

        String line =
                "<tr><td colspan=3></td></tr>"
                + "<tr><td colspan=3>Oct 23, 2001</td></tr>"
                + "<tr>"
                + "<td><nobr>4:21</nobr></td>"
                + "<td>SOMEUSER</td>"
                + "<tr><td><nobr>4:21</nobr></td><td>SOMEUSER</td><td>"
                + "some dummy words some dummy words some dummy words "
                + "</td></tr>";           

        editorKit.insertHTML(newdoc,
                             0,
                             line,
                             0,
                             0,
                             HTML.Tag.TABLE);
        contentPane.add(jScrollPane1, BorderLayout.CENTER);
        jTextPane1.setStyledDocument(newdoc);
        jScrollPane1.getViewport().add(jTextPane1, null);
    }
  
    /**Overridden so we can exit when window is closed*/
    protected void processWindowEvent(WindowEvent e)
    {
        super.processWindowEvent(e);
        if (e.getID() == WindowEvent.WINDOW_CLOSING)
        {
            System.exit(0);
        }
    }
    
    public static void main(String[] args)
    {
        JFrame frame = new Frame1();
        frame.show();
    }
}


Error Message:

java.lang.NullPointerException
        at javax.swing.text.FlowView.layout(FlowView.java:195)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:351)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:333)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:346)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:319)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:351)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:333)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:346)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:319)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:351)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:333)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.FlowView.layout(FlowView.java:199)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:351)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:333)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.text.BoxView.updateChildSizes(BoxView.java:351)
        at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:333)
        at javax.swing.text.BoxView.layout(BoxView.java:685)
        at javax.swing.text.BoxView.setSize(BoxView.java:382)
        at javax.swing.plaf.basic.BasicTextUI$RootView.setSize(BasicTextUI.java:1536)
        at javax.swing.plaf.basic.BasicTextUI.getPreferredSize(BasicTextUI.java:733)
        at javax.swing.JComponent.getPreferredSize(JComponent.java:1265)
        at javax.swing.JEditorPane.getPreferredSize(JEditorPane.java:1204)
        at javax.swing.ScrollPaneLayout.layoutContainer(ScrollPaneLayout.java:770)
        at java.awt.Container.layout(Container.java:838)
        at java.awt.Container.doLayout(Container.java:828)
        at java.awt.Container.validateTree(Container.java:906)
        at java.awt.Container.validateTree(Container.java:913)
        at java.awt.Container.validateTree(Container.java:913)
        at java.awt.Container.validateTree(Container.java:913)
        at java.awt.Container.validateTree(Container.java:913)
        at java.awt.Container.validate(Container.java:881)
        at java.awt.Window.dispatchEventImpl(Window.java:1566)
        at java.awt.Component.dispatchEvent(Component.java:3368)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:448)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:193)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:147)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:141)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:133)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:101)


Comments
EVALUATION The NullPointerException being seen in this case arises for a couple of reasons. Firstly, FlowView.layout() calls getContainer().repaint() without checking to see if the returned container is null. This has been fixed in a post-merlin workspace as bug 4522647. Now, there is the important question of why the container returned is sometimes null. This issue is addressed in 4522601. Although this test case has bumped up agains two known bugs, I beleive that this situation is still a user error. Neither the HTML 3.2 spec, nor our implementation, supports HTML tables inside of paragraphs. The element structure that the submitter is creating contains a table inside an HTML paragraph. This is causing them to bump up against 4522601. To fix their code, they should modify the line: editorKit.insertHTML(newDoc, 0, line, 0, 0, HTML.Tag.TABLE); to read: editorKit.insertHTML(newDoc, 0, line, 1, 0, HTML.Tag.TABLE); This will ensure that their table is being inserted outside of the default paragraph that is created when the HTMLDocument was constructed (thus it will not be a child of the paragraph). Even more simply, since the document is empty, the user could use the editor kit to read in the data like: java.io.StringReader re = new java.io.StringReader(line); try { editorKit.read(re, newdoc, 0); } catch (java.io.IOException ioe) { ioe.printStackTrace(); } catch (BadLocationException ble) { ble.printStackTrace(); } Closing as a user error. ###@###.### 2001-11-29
29-11-2001