JDK-4425177 : GlyphView.java uses shorts instead of ints
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.0
  • Priority: P2
  • Status: Closed
  • Resolution: Won't Fix
  • OS: windows_nt
  • CPU: x86
  • Submitted: 2001-03-13
  • Updated: 2001-03-13
  • Resolved: 2001-03-13
Description
Got the following error message from an application:

Exception occurred during event dispatching:
javax.swing.text.StateInvariantError: infinite loop in formatting
        at javax.swing.text.FlowView$FlowStrategy.layout(FlowView.java:429)
        at javax.swing.text.FlowView.layout(FlowView.java:182)
        at javax.swing.text.BoxView.setSize(BoxView.java:265)
        at javax.swing.text.BoxView.layout(BoxView.java:600)
        at javax.swing.text.BoxView.setSize(BoxView.java:265)
        at javax.swing.plaf.basic.BasicTextUI$RootView.paint(BasicTextUI.java:11
69)
        at javax.swing.plaf.basic.BasicTextUI.paintSafely(BasicTextUI.java:523)
        at javax.swing.plaf.basic.BasicTextUI.paint(BasicTextUI.java:657)
        at javax.swing.plaf.basic.BasicTextUI.update(BasicTextUI.java:636)
        at javax.swing.JComponent.paintComponent(JComponent.java:398)
        at javax.swing.JComponent.paint(JComponent.java:739)
        at javax.swing.JComponent.paintChildren(JComponent.java:523)
        at javax.swing.JComponent.paint(JComponent.java:748)
        at javax.swing.JComponent.paintChildren(JComponent.java:523)
        at javax.swing.JComponent.paint(JComponent.java:748)
        at javax.swing.JLayeredPane.paint(JLayeredPane.java:546)
        at javax.swing.JComponent.paintChildren(JComponent.java:523)
        at javax.swing.JComponent.paint(JComponent.java:719)
        at java.awt.GraphicsCallback$PaintCallback.run(GraphicsCallback.java:23)

        at sun.awt.SunGraphicsCallback.runOneComponent(SunGraphicsCallback.java:
54)
        at sun.awt.SunGraphicsCallback.runComponents(SunGraphicsCallback.java:91
)
        at java.awt.Container.paint(Container.java:960)
        at sun.awt.RepaintArea.paint(RepaintArea.java:298)
        at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:193)
        at java.awt.Component.dispatchEventImpl(Component.java:2665)
        at java.awt.Container.dispatchEventImpl(Container.java:1213)
        at java.awt.Window.dispatchEventImpl(Window.java:912)
        at java.awt.Component.dispatchEvent(Component.java:2499)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:319)
        at java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:10
3)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:84)

Expected behavior: The text is shown

Actual behavior: Throws exception and text is never shown

Was it working before? If so, what was changed?

This is the first time that we tested it.

To Reproduce:

Run Bug with a value like 40000 - it happens *EVERY* time.  We've tried
values down to 33000 and it still happens.

It's caused by bugs in javax.swing.text.GlyphView.java - which uses a short
to represent the offset and length into a Document.  However if you set the
document with text that is 32767 or less characters the problem never occurs.

There is no workaround other than not setting text that long !!

Standalone Test Case:

 import javax.swing.*;
 
 public class Bug {
    /** Run with a number indicating the number of characters in the string **/
    public static void main(String aArgs[])
      throws Throwable {
      if (aArgs.length != 1) {
         System.err.println("Usage: Bug [No of characters]");
         System.exit(1);
       }
 
       int lLength = Integer.parseInt(aArgs[0]);
 
       JFrame lFrame = new JFrame("TestMe");
 
       JTextPane lText = new JTextPane();
       lText.setEditable(false);
       lText.setOpaque(false);
       lFrame.getContentPane().add(lText);
       lText.setText(getText(lLength));
       lFrame.setSize(500, 500);
       lFrame.setVisible(true);
    }
 
    private static String getText(int aLen) {
       StringBuffer lBuff = new StringBuffer();
       while (aLen > 6) {
          lBuff.append("12 21 ");
          aLen -= 6;
       }
       while (aLen > 0) {
          lBuff.append("a");
          aLen--;
       }
       return lBuff.toString();
    }
 }

Comments
WORK AROUND Add some linefeeds to keep paragraphs under Math.MAX_SHORT in length or provide your own GlyphView implementation from the ViewFactory.
11-06-2004

EVALUATION This is intentional behavior. It is a huge memory savings to use shorts instead of ints since so many of these get created. The limitation is that the longest GlyphView can be is Math.MAX_SHORT characters at an offset of Math.MAX_SHORT from Element.getStartOffset(). We feel this is a reasonable restriction. Element.getStartOffset is limited to Math.MAX_INT so documents are not limited as claimed in the bug description. The GlyphView restriction simply means a paragraph cannot exceed Math.MAX_SHORT. timothy.prinzing@eng 2001-03-13
13-03-2001