NullPointerException in javax.swing.text.SimpleAttributeSet.addAttribute

789 Views Asked by At

Has anyone ever seen an exception like this (with version 1.6.0_11 of the JVM)?:

ERROR: java.lang.NullPointerException: null
    at java.util.Hashtable.put(null:-1)
    at javax.swing.text.SimpleAttributeSet.addAttribute(null:-1)
    at javax.swing.text.SimpleAttributeSet.addAttributes(null:-1)
    at javax.swing.text.StyledEditorKit.createInputAttributes(null:-1)
    at javax.swing.text.StyledEditorKit$AttributeTracker.updateInputAttributes(null:-1)
    at javax.swing.text.StyledEditorKit$AttributeTracker.caretUpdate(null:-1)
    at javax.swing.text.JTextComponent.fireCaretUpdate(null:-1)
    at javax.swing.text.JTextComponent$MutableCaretEvent.fire(null:-1)
    at javax.swing.text.JTextComponent$MutableCaretEvent.mouseReleased(null:-1)
    at java.awt.AWTEventMulticaster.mouseReleased(null:-1)
    at java.awt.AWTEventMulticaster.mouseReleased(null:-1)
    at java.awt.Component.processMouseEvent(null:-1)
    at javax.swing.JComponent.processMouseEvent(null:-1)
    at java.awt.Component.processEvent(null:-1)
    at java.awt.Container.processEvent(null:-1)
    at java.awt.Component.dispatchEventImpl(null:-1)
    at java.awt.Container.dispatchEventImpl(null:-1)
    at java.awt.Component.dispatchEvent(null:-1)
    at java.awt.LightweightDispatcher.retargetMouseEvent(null:-1)
    at java.awt.LightweightDispatcher.processMouseEvent(null:-1)
    at java.awt.LightweightDispatcher.dispatchEvent(null:-1)
    at java.awt.Container.dispatchEventImpl(null:-1)
    at java.awt.Window.dispatchEventImpl(null:-1)
    at java.awt.Component.dispatchEvent(null:-1)
    at java.awt.EventQueue.dispatchEvent(null:-1)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(null:-1)
    at java.awt.EventDispatchThread.pumpEventsForFilter(null:-1)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(null:-1)
    at java.awt.EventDispatchThread.pumpEvents(null:-1)
    at java.awt.EventDispatchThread.pumpEvents(null:-1)
    at java.awt.EventDispatchThread.run(null:-1)

The JTextComponent was just being clicked on when this happened (it certainly doesn't happen every time you click on it).

I wish I could tell you an easy way to reproduce this, but I can’t. It’s happening in a Java Swing application I maintain. It happens infrequently and the application is quite complex.

I know it’s a bit of a long shot just showing this stack trace, but I thought I’d try.

2

There are 2 best solutions below

0
On BEST ANSWER

Make sure you're updating the document only on the Swing Event Dispatch Thread.

6
On

The only thing I can see from this, is that a "null" has been inserted as InputAttribute of the Element under the caret.

I mean, from checking sources of these classes, I think the problem occurs at this point:

javax.swing.text.StyledEditorKit.createInputAttributes(null:-1)
javax.swing.text.StyledEditorKit$AttributeTracker.updateInputAttributes(null:-1)

From the source, at this point the editor kit recovers the current Element from the Document.

Excerpt from StyledEditorKit:

Element run;
currentParagraph = doc.getParagraphElement(start);
if (currentParagraph.getStartOffset() == start || dot != mark) {
    // Get the attributes from the character at the selection
    // if in a different paragrah!
    run = doc.getCharacterElement(start);
}
else {
    run = doc.getCharacterElement(Math.max(start-1, 0));
}
if (run != currentRun) {
    currentRun = run;
    createInputAttributes(currentRun, getInputAttributes());
}

This Element is not null, but its list of attributes contains a null element, which is then used directly in the addAttribute() and Hashtable.put(), causing the NPE.

So in my opinion, the only place where something bad can happen is in the Document. Check if you are using a custom Document for this JTextComponent, and be sure to check what exactly is done inside.

Because from tracing the whole thing, it can only be a problem at this place. The Event processing and caret update doesn't have an impact in it, it's just a regular update. The part after is only consequence, using the object passed. So it seems like the key point is in the Document.