United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6501991 java.awt.font.LineBreakMeasurer.nextOffset ArrayIndexOutOfBoundsException
JDK-6501991 : java.awt.font.LineBreakMeasurer.nextOffset ArrayIndexOutOfBoundsException

Details
Type:
Bug
Submit Date:
2006-12-07
Status:
Closed
Updated Date:
2011-05-18
Project Name:
JDK
Resolved Date:
2011-05-18
Component:
client-libs
OS:
windows_xp
Sub-Component:
javax.swing
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Backport:
Relates:
Relates:

Sub Tasks

Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b104, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Windows XP SP2

A DESCRIPTION OF THE PROBLEM :
Exception when using Arabic caracters


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
	at java.awt.font.LineBreakMeasurer.nextOffset(Unknown Source)
	at java.awt.font.LineBreakMeasurer.nextOffset(Unknown Source)
	at sun.swing.SwingUtilities2.clipString(Unknown Source)
	at javax.swing.SwingUtilities.layoutCompoundLabelImpl(Unknown Source)
	at javax.swing.SwingUtilities.layoutCompoundLabel(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonUI.layout(Unknown Source)
	at javax.swing.plaf.basic.BasicButtonUI.paint(Unknown Source)
	at javax.swing.plaf.ComponentUI.update(Unknown Source)
	at javax.swing.plaf.metal.MetalButtonUI.update(Unknown Source)
	at javax.swing.JComponent.paintComponent(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JViewport.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at javax.swing.JLayeredPane.paint(Unknown Source)
	at javax.swing.JComponent.paintChildren(Unknown Source)
	at javax.swing.JComponent.paintToOffscreen(Unknown Source)
	at javax.swing.BufferStrategyPaintManager.paint(Unknown Source)
	at javax.swing.RepaintManager.paint(Unknown Source)
	at javax.swing.JComponent.paint(Unknown Source)
	at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
	at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
	at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
	at java.awt.Container.paint(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
	at javax.swing.RepaintManager.seqPaintDirtyRegions(Unknown Source)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(Unknown Source)
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)
	at java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.awt.EventDispatchThread.run(Unknown Source)


REPRODUCIBILITY :
This bug can be reproduced always.

                                    

Comments
EVALUATION

What is happening in LineBreakMeasurer.nextOffset can be demonstrated more simply :

import java.awt.font.*;
import java.text.*;

public class Test {

    public static void main(String[] args) {
        FontRenderContext frc = new FontRenderContext(null,false,false);
         AttributedString aString = new AttributedString("\u0634");
         LineBreakMeasurer measurer =
             new LineBreakMeasurer(aString.getIterator(), frc);
        System.out.println("nchars="+measurer.nextOffset(-6));
    }

}

% java Test
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
        at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:346)
        at java.awt.font.LineBreakMeasurer.nextOffset(LineBreakMeasurer.java:310)
        at Test.main(Test.java:11) 

This is not new in JDK 1.6. Passing in a negative offset is clearly incorrect.

What is new is the code in SwingUtilities2 that passes in this value.
It was introduced in the fix for 4374406, which resolved that Swing did
not use TextLayout in some cases it should. This example is when Swing
displays '...' to terminate a string that cannot fit in the space provided.
The calculation presumes that the space provided is at least sufficient to
fit '...' and so subtracts the width of '...' from the available width
to determine the with available to pass to LineBreakMeasurer.nextOffset().
When this ends up negative, the exception occurs.
Swing probably should simply treat a negative value as being zero.
                                     
2006-12-07
EVALUATION

we can do something like this in SwingUtilities2.clipString:
--
         availTextWidth -= SwingUtilities2.stringWidth(c, fm, clipString);
+        if (availTextWidth <= 0) {
+            //can not fit any characters
+            return clipString;
+        }
+
--

This is how non i18n case works anyways.
                                     
2007-07-17



Hardware and Software, Engineered to Work Together