Name: rmT116609 Date: 05/21/2002
FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)
FULL OPERATING SYSTEM VERSION :
Linux simia 2.2.19 #20 Tue May 15 20:53:22 CEST 2001 i686 unknown libc-2.1.3-141
& Windows 2000
A DESCRIPTION OF THE PROBLEM :
When adjusting dot/mark after a DocumentEvent, DefaultCaret calls directly into the view hierarchy (addHighlight etc. see stack trace). It should not do so because the hierarchy may be in an unstable state if it has not handled the event yet (i.e the caret's event listener is executed before the BasicTextUI's which then informs the Views). Instead, it should defer (SwingUtilities.invokeLater) this until the Views have adjusted to the Document change.
This bug only seems to occur in 1.4, but I don't see why it worked in 1.3 (the relevant code doesn't seem to have been changed), so maybe it is only harder to produce it.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the code.
EXPECTED VERSUS ACTUAL BEHAVIOR :
No exception (obviously)
Exception (and sometimes an infinite loop).
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.swing.text.StateInvariantError: infinite loop in formatting
at javax.swing.text.FlowView$FlowStrategy.layout(FlowView.java:403)
at javax.swing.text.FlowView.layout(FlowView.java:182)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at javax.swing.text.BoxView.updateChildSizes(BoxView.java:348)
at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:330)
at javax.swing.text.BoxView.layout(BoxView.java:682)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at javax.swing.text.BoxView.updateChildSizes(BoxView.java:343)
at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:316)
at javax.swing.text.BoxView.layout(BoxView.java:682)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at javax.swing.text.BoxView.updateChildSizes(BoxView.java:348)
at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:330)
at javax.swing.text.BoxView.layout(BoxView.java:682)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at javax.swing.text.BoxView.updateChildSizes(BoxView.java:348)
at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:330)
at javax.swing.text.BoxView.layout(BoxView.java:682)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at javax.swing.text.BoxView.updateChildSizes(BoxView.java:348)
at javax.swing.text.BoxView.setSpanOnAxis(BoxView.java:330)
at javax.swing.text.BoxView.layout(BoxView.java:682)
at javax.swing.text.BoxView.setSize(BoxView.java:379)
at
javax.swing.plaf.basic.BasicTextUI$RootView.setSize(BasicTextUI.java:15
28)
at javax.swing.plaf.basic.BasicTextUI.damageRange(BasicTextUI.java:998)
at javax.swing.plaf.basic.BasicTextUI.damageRange(BasicTextUI.java:979)
at
javax.swing.text.DefaultHighlighter.addHighlight(DefaultHighlighter.jav
a:107)
at javax.swing.text.DefaultCaret.handleMoveDot(DefaultCaret.java:878)
at javax.swing.text.DefaultCaret.moveDot(DefaultCaret.java:851)
at
javax.swing.text.DefaultCaret$UpdateHandler.removeUpdate(DefaultCaret.j
ava:1515)
at
javax.swing.text.AbstractDocument.fireRemoveUpdate(AbstractDocument.jav
a:242)
at
javax.swing.text.AbstractDocument.handleRemove(AbstractDocument.java:61
1)
at javax.swing.text.AbstractDocument.remove(AbstractDocument.java:575)
at CaretBug$1.actionPerformed(CaretBug.java:39)
at javax.swing.Timer.fireActionPerformed(Timer.java:271)
at javax.swing.Timer$DoPostEvent.run(Timer.java:201)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:443)
at
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThre
ad.java:190)
at
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread
.java:144)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:130)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:98)
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.swing.text.html.*;
import javax.swing.text.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
public class CaretBug
{
public static void main(String[] args)
throws Exception
{
HTMLEditorKit k = new HTMLEditorKit();
final HTMLDocument d = new HTMLDocument();
k.read(new StringReader("<html><table><td><p>ABC<td><p>DEF"), d, 0);
final JEditorPane pane = new JEditorPane();
pane.setEditorKit(k);
pane.setDocument(d);
pane.setCaret(new DefaultCaret());
JFrame f = new JFrame();
f.getContentPane().add(new JScrollPane(pane));
Timer t = new Timer(3000, new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
try
{
pane.select(3, 6);
d.remove(5, 1);
d.remove(3, 1);
}
catch (Exception x)
{
x.printStackTrace();
}
}
});
t.setRepeats(false);
t.start();
f.pack(); f.show();
}
}
---------- END SOURCE ----------
CUSTOMER WORKAROUND :
Call updateUI() after setDocument() so that hopefully the UIs DocumentListener is executed before the Caret's.
Release Regression From : 1.3.1_03
The above release value was the last known release where this
bug was known to work. Since then there has been a regression.
(Review ID: 146200)
======================================================================