JDK-6420152 : REGRESSION: Closing an output tab in NetBeans produces ArrayIndexOutOfBoundsException
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0,6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2006-05-01
  • Updated: 2011-01-31
  • Resolved: 2006-08-02
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
6 b94Fixed
Related Reports
Duplicate :  
Relates :  
Description
In NetBeans when you try to close an output tab, you get the following exception:

java.lang.ArrayIndexOutOfBoundsException: 1 >= 1
    at java.util.Vector.elementAt(Vector.java:431)
    at javax.swing.JTabbedPane.getComponentAt(JTabbedPane.java:1201)
    at javax.swing.JTabbedPane.getSelectedComponent(JTabbedPane.java:637)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane.sel(CloseButtonTabbedPane.java:58)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane.access$200(CloseButtonTabbedPane.java:38)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane$CBTPPolicy.getDefaultComponent(CloseButtonTabbedPane.java:80)
    at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(SortingFocusTraversalPolicy.java:131)
    at javax.swing.SortingFocusTraversalPolicy.getComponentAfter(SortingFocusTraversalPolicy.java:244)
    at javax.swing.LayoutFocusTraversalPolicy.getComponentAfter(LayoutFocusTraversalPolicy.java:88)
    at java.awt.Container.nextFocusHelper(Container.java:3076)
    at java.awt.Component.removeNotify(Component.java:6459)
    at java.awt.Container.removeNotify(Container.java:2551)
    at javax.swing.JComponent.removeNotify(JComponent.java:4624)
    at javax.swing.text.JTextComponent.removeNotify(JTextComponent.java:1623)
    at java.awt.Container.removeNotify(Container.java:2545)
    at javax.swing.JComponent.removeNotify(JComponent.java:4624)
    at java.awt.Container.removeNotify(Container.java:2545)
    at javax.swing.JComponent.removeNotify(JComponent.java:4624)
    at java.awt.Container.removeNotify(Container.java:2545)
    at javax.swing.JComponent.removeNotify(JComponent.java:4624)
    at org.netbeans.core.output2.OutputTab.removeNotify(OutputTab.java:49)
    at java.awt.Container.remove(Container.java:1123)
    at javax.swing.JTabbedPane.removeTabAt(JTabbedPane.java:955)
    at javax.swing.JTabbedPane.remove(JTabbedPane.java:1003)
    at org.netbeans.core.output2.ui.AbstractOutputWindow.remove(AbstractOutputWindow.java:141)
    at org.netbeans.core.output2.Controller.close(Controller.java:557)
    at org.netbeans.core.output2.OutputWindow.closeRequest(OutputWindow.java:60)
    at org.netbeans.core.output2.ui.AbstractOutputWindow.propertyChange(AbstractOutputWindow.java:54)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:347)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:276)
    at java.awt.Component.firePropertyChange(Component.java:7802)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane.fireCloseRequest(CloseButtonTabbedPane.java:278)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane.access$800(CloseButtonTabbedPane.java:38)
    at org.netbeans.core.output2.ui.CloseButtonTabbedPane$CloseButtonListener.eventDispatched(CloseButtonTabbedPane.java:377)
    at java.awt.Toolkit$SelectiveAWTEventListener.eventDispatched(Toolkit.java:2360)
    at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2252)
    at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2251)
    at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2251)
    at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2251)
    at java.awt.Toolkit$ToolkitEventMulticaster.eventDispatched(Toolkit.java:2251)
    at java.awt.Toolkit.notifyAWTEventListeners(Toolkit.java:2210)
    at java.awt.Component.dispatchEventImpl(Component.java:4305)
    at java.awt.Container.dispatchEventImpl(Container.java:2042)
    at java.awt.Component.dispatchEvent(Component.java:4237)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4248)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3912)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3842)
    at java.awt.Container.dispatchEventImpl(Container.java:2028)
    at java.awt.Window.dispatchEventImpl(Window.java:2300)
    at java.awt.Component.dispatchEvent(Component.java:4237)
[catch] at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

This is likely the result of NetBeans trying to work around the problem that has now been solved by 6368047. Perhaps their code doesn't work well with our fix.

Comments
EVALUATION This also fixes 6426366, a similar exception with IntelliJ IDEA.
24-07-2006

EVALUATION The root of the problem is in the current implementation of removeTabAt. In essence, it does the following: - pages.removeElementAt(index) - super.remove(componentForIndex) - update selection to valid index This would be fine if the only notification that was sent out was from the last step, updating the selection. However, the call to remove the component results in a call to the JTabbedPane's focus traversal policy to get a focusable component. The focus traversal policy in NetBeans and the attached test case, calls back into JTabbedPane.getSelectedComponent(). Unfortunately, JTabbedPane isn't prepared to service this request. It's only part of the way through updating for the removal. So let's say for example that the last tab in a tabbed pane is selected and we call removeTabAt for that index: - First, the pages array is updated. - Then the component is removed, firing removeNotify() - When the focus traversal policy then calls back in to get the selected component, JTabbedPane tries to return the component for the index that was selected prior to the removal (it hasn't updated yet). - This results in the ArrayIndexOutOfBoundsException To fix this, the sequence in JTabbedPane.removeTabAt has been changed to: - pages.removeElementAt(index) - update selection to valid index - super.remove(componentForIndex) As a result, everything is in a consistent state when both the stateChanged is fired and when the remove happens (which calls into the focus traversal policy). Note: I've also updated a regression test as a result of this fix: test/javax/swing/JTabbedPane/5089436/bug5089436.java As part of the test, it was ensuring that removed components had their visibility set to true. This is correct, however it doesn't necessarily have to happen by the time the stateChanged event is fired. It no longer will after this fix, and so I've re-arranged how this assertion is tested.
21-07-2006

EVALUATION DELETED COMMENT
13-06-2006