JDK-6501991 : java.awt.font.LineBreakMeasurer.nextOffset ArrayIndexOutOfBoundsException
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-12-07
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7
6u4Fixed 7 b20Fixed
Related Reports
Relates :  
Relates :  
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 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.
17-07-2007

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.
07-12-2006