Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4353673
Votes 43
Synopsis Array out of bounds exceptions when using a JTextPane with embedded components
Category java:classes_swing
Reported Against 1.3
Release Fixed 1.4(merlin-beta)
State 10-Fix Delivered, bug
Priority: 3-Medium
Related Bugs 4335120 , 4391503 , 4450832
Submit Date 17-JUL-2000
Description





java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


When a JTextPane is given a JComponent to display within it, array out of
bounds exceptions are thrown. Here is some sample code. Run it, put the cursor
after the JTable and press enter. This should trigger the problem. It's /very/
annoying and /needs/ to be fixed :) This operation used to work fine, so this
is a recent bug.


import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * Small demo to show that the textpane is throwing exceptions for no
 * apparent reason. The exception is caused by just doing things with the
 * textpane such as pressing 'enter' after the embedded table.
 * Embedded components are definitely at fault here.
 * Here is the exception:
 *
Exception occurred during event dispatching:
java.lang.ArrayIndexOutOfBoundsException
	at javax.swing.SizeRequirements.calculateAlignedPositions
(SizeRequirements.java:338)
	at javax.swing.OverlayLayout.layoutContainer(OverlayLayout.java:207)
	at java.awt.Container.layout(Container.java:686)
	at java.awt.Container.doLayout(Container.java:676)
	at java.awt.Container.validateTree(Container.java:750)
	at java.awt.Container.validateTree(Container.java:757)
	at java.awt.Container.validateTree(Container.java:757)
	at java.awt.Container.validateTree(Container.java:757)
	at java.awt.Container.validateTree(Container.java:757)
	at java.awt.Container.validate(Container.java:728)
	at javax.swing.RepaintManager.validateInvalidComponents
(RepaintManager.java:313)
	at javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run
(SystemEventQueueUtilities.java:204)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:154)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:317)
	at java.awt.EventDispatchThread.pumpOneEvent
(EventDispatchThread.java:103)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:84)

 */
public class TextPaneDemo extends JFrame
{

   public TextPaneDemo()
   {
      JTextPane pane = new JTextPane();
      try
      { pane.getDocument().insertString(0, "Some random text", null); }
      catch (Exception e)
      { e.printStackTrace(); }
      pane.insertComponent(new JScrollPane(new JTable(20, 10)));

      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.NORTH, pane);
      pack();
      setVisible(true);
      addWindowListener(new ByeByeListener());
   }

   public static void main(String[] argv)
   {
      TextPaneDemo demo = new TextPaneDemo();
   }

   private class ByeByeListener extends WindowAdapter
   {
      public void windowClosing(WindowEvent e)
      {
         System.exit(0);
      }
   }
}
(Review ID: 106747) 
======================================================================




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

1) Create a JTextPane
2) Create a JTable in a JScrollPane (in order to get column headings, etc.)
3) Insert JScrollPane into JTextPane using insertComponent
4) Click immediately after the JTable and type

Result: ArrayOutOfBoundsException thrown on each keystroke in the Java Container
layout code.

Problem does not occur for insertComponent of a simple JTable (no JScrollPane).

Problem does not occur for insertComponent of JScrollPane containing other
components (e.g. JTextArea).

The following code will illustrate the problem:

import javax.swing.*;
import javax.swing.text.*;

class TypingTest{
    static public void main(String args[]){
        JFrame frame = new JFrame("JTextPane typing test");
        frame.setSize(500,300);
        frame.setVisible(true);
                
        JTextPane pane = new JTextPane();
        frame.getContentPane().add(pane);

        pane.replaceSelection("Click immediately after the JTable and start "
           + "typing, get ArrayIndexOutOfBoundsException on each keystroke. ");
        pane.setCaretPosition(pane.getStyledDocument().getLength());

        Object[] columns = {"This", "is", "a", "JTable"};
        Object[][] data = {{"table", "", "", ""}, {"", "data", "", ""},
                           {"", "", "goes", ""}, {"", "", "", "here"}};

        //this doesn't work:
        JScrollPane jsp = new JScrollPane(new JTable(data,columns));
        jsp.setPreferredSize(new java.awt.Dimension(500,83));
	pane.insertComponent(jsp);

        //this works: pane.insertComponent(new JTable(data,columns));

        //this works:
        //JScrollPane jsp = new JScrollPane(new JTextArea("A\nB\nC\nD\n"));
        //jsp.setPreferredSize(new java.awt.Dimension(500,83));
        //pane.insertComponent(jsp);

        frame.addWindowListener( new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent e)
                 {System.exit(0); }  }  );
      
    }
}
(Review ID: 107307)
======================================================================




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

In a JTextPane I want to insert a JLabel and then some text.  I want to do this
programatically.  Under JRE 1.2.2 the following code works well.  Under 1.3 it
report errors intermittantly.  Following is a simple sample JApplet that
demonstates the problem followed by the runtime errors.  The real product is an
IRC chat applet that is ready to deploy.  You can see it on
www.ircplus.com/support/chat.asp.  Under 1.2.2 it works well under 1.3 it
crashes.  This is going to be real problem for our customers.

Simple Applet Code

//Title:       Test Project
//Version:
//Copyright:   Copyright (c) 2000
//Author:      Brian Akehurst
//Company:     Mad-Web Networks LLC
//Description: Test for inserting labels into Java JTextPane
package Tests;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import javax.swing.text.*;

public class TextPaneTest extends JApplet {
  boolean isStandalone = false;
  JPanel jPanel1 = new JPanel();
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel2 = new JPanel();
  JPanel jPanel3 = new JPanel();
  JLabel jLabel1 = new JLabel();
  JScrollPane jScrollPane1 = new JScrollPane();
  JTextPane jTextPane1 = new JTextPane();

  //Construct the applet
  public TextPaneTest() {
  }

  //Initialize the applet
  public void init() {
    try  {
      jbInit();
    }
    catch(Exception e)  {
      e.printStackTrace();
    }
  }

  //Component initialization
  private void jbInit() throws Exception {
    this.setSize(new Dimension(400,300));
    jPanel1.setLayout(borderLayout1);
    jLabel1.setText("Test for inserting components into JTextPane");
    jTextPane1.setPreferredSize(new Dimension(300, 200));
    jScrollPane1.setPreferredSize(new Dimension(300, 200));
    this.getContentPane().add(jPanel1, BorderLayout.CENTER);
    jPanel1.add(jPanel2, BorderLayout.CENTER);
    jPanel2.add(jScrollPane1, null);
    jScrollPane1.getViewport().add(jTextPane1, null);
    jPanel1.add(jPanel3, BorderLayout.NORTH);
    jPanel3.add(jLabel1, null);

   for (int i = 1; i < 21 ; i++) {

   //Get the insert position and insert the label component

      Position pos = jTextPane1.getStyledDocument().getEndPosition();
      jTextPane1.setSelectionStart(pos.getOffset()-1);
      jTextPane1.insertComponent(new JLabel("Label "+new Integer(i).toString()
+" "));

   //reset the selection start position
      jTextPane1.setSelectionStart(pos.getOffset()-1);

   //Contruct a string and insert it after the label

    String stg = new String("Text String "+new Integer(i).toString()+"\n");
    int selStart = jTextPane1.getSelectionStart();
    jTextPane1.replaceSelection(stg);
    jTextPane1.setSelectionStart(selStart+stg.length());
   }

  }

  //Start the applet
  public void start() {
  }

  //Stop the applet
  public void stop() {
  }

  //Destroy the applet
  public void destroy() {
  }

  //Get Applet information
  public String getAppletInfo() {
    return "Applet Information";
  }

  //Get parameter info
  public String[][] getParameterInfo() {
    return null;
  }
  // static initializer for setting look & feel
  static {
    try {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName
());
    }
    catch (Exception e) {}
  }

}  

Errors

java.lang.ArrayIndexOutOfBoundsException
        at javax.swing.SizeRequirements.calculateAlignedPositions(SizeRequiremen
ts.java:338)
        at javax.swing.OverlayLayout.layoutContainer(OverlayLayout.java:207)
        at java.awt.Container.layout(Container.java:686)
        at java.awt.Container.doLayout(Container.java:676)
        at java.awt.Container.validateTree(Container.java:750)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validateTree(Container.java:757)
        at java.awt.Container.validate(Container.java:728)
        at sun.applet.AppletPanel.run(AppletPanel.java:347)
        at java.lang.Thread.run(Thread.java:484)
(Review ID: 109232)
======================================================================




java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)

Here's a forum message that describes the problem.
I have had the same problem in my own code (far less minimal than
this code):

I'm traying to place JButtons in each row of an Document (JTextPane). One Button
at the end of the Document is not a problem,
                              but if placing anything after a Button... There's
a peace of Code and the Error Message that I'm getting.

                              //...

                              public class WindowAR extends JWindow {

                              //...

                              Style btn = jTextPaneErg.addStyle("button",
regular);
                              JButton button = new JButton();

                              //...

                              //Component initialization
                              private void jbInit() throws Exception {

                              button.setMargin(new Insets(0,0,0,0));
                              button.addActionListener(new ActionListener() {
                              public void actionPerformed(ActionEvent e) {
                              }
                              });
                              StyleConstants.setAlignment(btn,
StyleConstants.ALIGN_CENTER);
                              StyleConstants.setComponent(btn, button);

                              //...

                              // Show Objects
                              public void showARObjects(java.util.List list) {
                              StyledDocument doc =
arjTextPane.getStyledDocument();
                              ListIterator i = list.listIterator();

                              while (i.hasNext()) {
                              //...
                              arObject = (ARObject) i.next();

                              doc.insertString(doc.getLength(), " ", icon);
                              doc.insertString(doc.getLength(), " Area: "
arObject.area, italic);
                              doc.insertString(doc.getLength(), " ", btn); //
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                              doc.insertString(doc.getLength(), " Code: "
arObject.code, italic);
                              doc.insertString(doc.getLength(), "\n", regular);
                              }

                              //...

                              }
                              //EOF

                              ! Error !! Error !! Error !! Error !! Error !!
Error !! Error !! Error !! Error !...
                              Output Window:

                              Exception occurred during event dispatching:
                              java.lang.ArrayIndexOutOfBoundsException
                              at
javax.swing.SizeRequirements.calculateAlignedPositions(SizeRequirements.java:338
) 
                              at
javax.swing.OverlayLayout.layoutContainer(OverlayLayout.java:207)
                              at java.awt.Container.layout(Container.java:686)
                              at java.awt.Container.doLayout(Container.java:676)
                              at
java.awt.Container.validateTree(Container.java:750)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at java.awt.Container.validate(Container.java:728)
                              at
javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:313)
                              at
javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQueueU
tilities.java:204)
                              at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:154)
                              at
java.awt.EventQueue.dispatchEvent(EventQueue.java:317)
                              at
java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:103)
                              at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
                              at
java.awt.EventDispatchThread.run(EventDispatchThread.java:84) Exception occurred
during event dispatching:
                              java.lang.ArrayIndexOutOfBoundsException
                              at
javax.swing.SizeRequirements.calculateAlignedPositions(SizeRequirements.java:338
) 
                              at
javax.swing.Over
layLayout.layoutContainer(OverlayLayout.java:207)
                              at java.awt.Container.layout(Container.java:686)
                              at java.awt.Container.doLayout(Container.java:676)
                              at
java.awt.Container.validateTree(Container.java:750)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              at
java.awt.Container.validateTree(Container.java:757)
                              //...
(Review ID: 110389)
======================================================================
Posted Date : 2005-07-22 03:26:06.0
Work Around
This will potentially lock you into the current implementation of ComponentView, but it'll work at least until 1.4:

      component.addHierarchyListener(new HierarchyListener() {
          private Container oldParent;
          public void hierarchyChanged(HierarchyEvent e) {
              Container parent = component.getParent();

              if (parent != oldParent) {
                  if (oldParent != null) {
                      textPane.remove(oldParent);
                  }
                  oldParent = parent;
              }
          }
      });

Where component is the Component being added to the text pane (JScrollPane in the first example).
  xxxxx@xxxxx   2000-11-20




This appears to be a bug in SizeRequirements where the xChildren (also
yChildren) array is not the same length as the offset and
                              span arrays. Calling invalidateLayout on the
button's OverlayLayout will clear the cached [xy]Children arrays and reallocate
them at
                              the correct length. Here's a method to call after
adding a new component (button but could be any JComponent) to a JTextPane:

                              /**
                              * Clear cached size calculations to work around
                              * ArrayIndexOutOfBounds exception
                              * in SizeRequirements. Button is a JComponent
                              * that has its own internal OverlayLayout that
                              * must be invalidated.
                              */
                              private void invalidateButtonLayout(JButton
button)
                              {
                              LayoutManager layout =
button.getParent().getLayout();
                              if(layout instanceof OverlayLayout) {
                              ((OverlayLayout)layout).
                              invalidateLayout((Container)(button.getParent()));
                              }
                              }
(Review ID: 110389)
======================================================================
Evaluation
This is happening because we are not forwarding setParent(null), so that ComponentView does not know when to remove the Component it creates from the JTextComponent.
  xxxxx@xxxxx   2000-11-20

The problem with forwarding setParent(null) is that it can potentially cause invoking a method on a large amount of Views every time they are removed.
Instead ComponentView should install a DocumentListener. When the range it represents is removed, it should do the necessary cleanup. This should be acceptable as typically not that many Components are created on a particular page.
  xxxxx@xxxxx   2000-12-07

We decided to change View to forward setParent(null) to all children. ComponentView has been changed to recognize this and properly remove the Component it represents. This also fixes bugid 4335120.
  xxxxx@xxxxx   2001-01-10
Comments
  
  Include a link with my name & email   

Submitted On 30-AUG-2000
magsy
So is this going to be fixed? Putting JComponents into
JTextPanes is such a cool feature. You can't leave it broken!


Submitted On 26-OCT-2000
eflambe
I have the same problem : inserting components in a 
JTextPane doesn't work at all.
getComponentCount doesn't work too.


Submitted On 02-NOV-2000
stevenhale
We're eager to go up to 1.3 but our system relies on this 
feature. It would be nice to know if it's going to be fixed 
in the next week, month, year, decade...


Submitted On 13-NOV-2000
bhaidri
It would be great if we can deploy our application to our users and allow them
to use any JVM they want.  However, in this case we have to insist they use 
1.2.2 or lower.  If they already have 1.3 installed, it would be a big inconvenience
for them.


Submitted On 14-NOV-2000
eflambe
I HAVE THE MOST SIMPLE OF THE WORKAROUNDS!
Well, it works for our product.
Just take the ComponentView.java class of the JDK1.2, 
compile it and replace the class (and its inner classes) in 
the rt.jar of the JDK1.3.
So that you run with the JDK1.3 but with the ComponentView 
classes of the 1.2.
Good luck!


Submitted On 09-JAN-2002
magsy
And now, I cannot get any component to display in any
JTextPane in 1.4beta 3. Someone wanna send me a working example?


Submitted On 14-JAN-2002
shan-man
Here's an example that shows the insertion of JButtons into 
a JTextPane. It works fine for me. When it launches, it 
shows a JTextPane and a button at the bottom. Click the 
button to add buttons into the
JTextPane.


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ComponentTest extends JFrame {
    
    JTextPane tp = new JTextPane();
    JButton b = new JButton("Run Test");
    private int count = 0;
    
    public ComponentTest() {
        setTitle("ComponentTest");
        setSize(500, 400);
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });
        
        tp.setText("foo");
        
        b.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                tp.insertComponent(new JButton("Button " + 
count++));
            }
        });
        
        getContentPane().add(tp, BorderLayout.CENTER);
        getContentPane().add(b, BorderLayout.SOUTH);
    }
    
    public static void main(String[] args) {
        ComponentTest test = new ComponentTest();
        test.setVisible(true);
    }
}


Submitted On 07-FEB-2002
magsy
I removed the tp.setText and replaced it with:

try
      { tp.setPage(new URL("file:///tmp/moo.html")); }
      catch (Exception e)
      { e.printStackTrace(); }
      try
      { Thread.sleep(2000); }
      catch (Exception e)
      {}
      tp.setEditable(true);

And it inserts blank spaces. Fantastic. Looks like this is
still broken. Can anyone comment?


Submitted On 12-FEB-2002
shan-man
Regarding the previous comment:
I have filed a new bug regarding this issue. The problem is 
with inserting components when using an HTMLEditorKit. Bug 
4636235 will appear in the database shortly.


Submitted On 16-DEC-2002
iforgot
Suggested workaround (component.addHierarchyListener) does not work all the time
anymore.
Here is the error I get (my config is java 1.3.1 on MacOS X 10.2):

java.lang.NullPointerException
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Component.show(Component.java:912)
	at java.awt.Window.show(Window.java:391)
	at java.awt.Component.show(Component.java:941)
	at java.awt.Component.setVisible(Component.java:898)

for info, here is line 602 in Container.java:
	    count -= component[i].createHierarchyEvents(id, changed,

Help !  I need a working workaround !!!


Submitted On 16-DEC-2002
iforgot
actually, I get the following exception before the one I report above. And these 2 exceptions are only thrown once in a while.

Exception occurred during event dispatching:
java.lang.NullPointerException
	at java.awt.Container.createHierarchyEvents(Container.java:602)
	at java.awt.Container.addImpl(Container.java:388)
	at java.awt.Container.add(Container.java:262)
	at javax.swing.text.ComponentView.setComponentParent(ComponentView.java:258)
	at javax.swing.text.ComponentView$1.run(ComponentView.java:220)
	at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:149)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:332)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:126)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:88)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:80)


Submitted On 21-AUG-2003
troggan
Yep, the bug is back :((((


Submitted On 21-AUG-2003
iforgot
aaargh! The bug is BACK in 1.4.2 !

java.lang.ArrayIndexOutOfBoundsException: No such child: 0
        at java.awt.Container.getComponent(Container.java:237)
        at 
javax.swing.text.ComponentView$Invalidator.cacheChildSizes(Com
ponentView.java:399)
        at 
javax.swing.text.ComponentView$Invalidator.doLayout(Component
View.java:383)
        at java.awt.Container.validateTree(Container.java:1092)
        at java.awt.Container.validateTree(Container.java:1099)
        at java.awt.Container.validateTree(Container.java:1099)
        at java.awt.Container.validateTree(Container.java:1099)
        at java.awt.Container.validate(Container.java:1067)
        at 
javax.swing.RepaintManager.validateInvalidComponents(RepaintMa
nager.java:353)
        at 
javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.ru
n(SystemEventQueueUtilities.java:116)
        at 
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:178)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:454)
        at 
java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDis
patchThread.java:201)
        at 
java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispa
tchThread.java:151)
        at 
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.ja
va:145)
        at 
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.ja
va:137)
        at 
java.awt.EventDispatchThread.run(EventDispatchThread.java:100)


Submitted On 22-AUG-2003
shan-man
Actually, this bug hasn't come back. It's a new bug with a 
similar error message. We already know about it and are 
tracking it under 4839979. Thanks!



PLEASE NOTE: JDK6 is formerly known as Project Mustang