JDK-5056403 : REGRESSION: JTabbedPane setFocusable(false) and removing tabs
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 5.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 2004-06-02
  • Updated: 2004-10-13
  • Resolved: 2004-09-22
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.
Other JDK 6
5.0u3Fixed 6 betaFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description

Name: gm110360			Date: 06/02/2004


FULL PRODUCT VERSION :
java version "1.5.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta-b32c)
Java HotSpot(TM) Client VM (build 1.5.0-beta-b32c, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows XP Home

A DESCRIPTION OF THE PROBLEM :
An exception is thrown when a tab is removed from a tabbedpane and another tab is selected after tabbedPane.setFocusable(false) has been called.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the example prog given.  Close the 3rd tab by right clicking on it and selecting close.  Then Click on the second tab and an exception will be thrown.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No exception.
ACTUAL -
Exception is thrown, no functionality difference that I can see.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.ArrayIndexOutOfBoundsException: 2
	at javax.swing.plaf.basic.BasicTabbedPaneUI.getTabBounds(BasicTabbedPaneUI.java:1297)
	at javax.swing.plaf.basic.BasicTabbedPaneUI.getTabBounds(BasicTabbedPaneUI.java:1237)
	at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.mousePressed(BasicTabbedPaneUI.java:3200)
	at java.awt.AWTEventMulticaster.mousePressed(AWTEventMulticaster.java:221)
	at java.awt.Component.processMouseEvent(Component.java:5460)
	at javax.swing.JComponent.processMouseEvent(JComponent.java:3052)
	at java.awt.Component.processEvent(Component.java:5228)
	at java.awt.Container.processEvent(Container.java:1961)
	at java.awt.Component.dispatchEventImpl(Component.java:3931)
	at java.awt.Container.dispatchEventImpl(Container.java:2019)
	at java.awt.Component.dispatchEvent(Component.java:3779)
	at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4203)
	at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3880)
	at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3813)
	at java.awt.Container.dispatchEventImpl(Container.java:2005)
	at java.awt.Window.dispatchEventImpl(Window.java:1757)
	at java.awt.Component.dispatchEvent(Component.java:3779)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
	at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:234)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:163)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:157)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:149)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

class TabbedPaneBug extends JFrame
{
	JTabbedPane tabbedPane=new JTabbedPane(JTabbedPane.BOTTOM);
	JPopupMenu popupMenu;
	public TabbedPaneBug()
	{
		tabbedPane.setFocusable(false);
		JLabel label1=new JLabel("Label1"), label2=new JLabel("Label2"), label3=new JLabel("Label3");
		popupMenu=new JPopupMenu();
		JMenuItem closeTab=new JMenuItem("Close");
		PopupListener pl=new PopupListener();
		closeTab.addActionListener(pl);
		popupMenu.add(closeTab);
		tabbedPane.addMouseListener(pl);
		tabbedPane.addTab("Title1", label1);
		tabbedPane.addTab("Title2", label2);
		tabbedPane.addTab("Title3", label3);
		getContentPane().add(tabbedPane);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(500,500);
		setVisible(true);
	}
	public static void main(String args[])
	{
		new TabbedPaneBug();
	}
	class PopupListener implements MouseListener, ActionListener
	{
		int x,y;
		public void actionPerformed(ActionEvent e)
		{
			final int index=tabbedPane.indexAtLocation(x,y);
			//This is where I think the problem is, it seems like a syncronization problem, which
			//is why I forced it to remove the tab in the event thread, but that didn't help.
			tabbedPane.removeTabAt(index);
		}
		public void mouseEntered(MouseEvent e){}
		public void mouseExited(MouseEvent e){}
		public void mouseClicked(MouseEvent e)
        	{showPopup(e);}
		public void mousePressed(MouseEvent e)
        	{showPopup(e);}
		public void mouseReleased(MouseEvent e)
        	{showPopup(e);}
    	private void showPopup(MouseEvent e)
    	{
			x=e.getX();
			y=e.getY();
        	if (e.isPopupTrigger()&&tabbedPane.indexAtLocation(x,y)>=0)
            	popupMenu.show(e.getComponent(),e.getX(), e.getY());
    	}
	}
}

---------- END SOURCE ----------

Release Regression From : 1.4.2
The above release value was the last known release where this 
bug was known to work. Since then there has been a regression.

(Incident Review ID: 275928) 
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon mustang FIXED IN: mustang INTEGRATED IN: mustang
23-09-2004

EVALUATION Name: sh120115 Date: 06/02/2004 There are a couple of places in BasicTabbedPaneUI that try to get the bounds and repaint the tab represented by oldFocusIndex. This code fails to account for the fact that the tab represented by oldFocusIndex may have been removed. ###@###.### 2004-06-02 BasicTabbedPaneUI was a bit inconsistant in it's handling of the focusIndex (tab index that focus indicator is rendered on, not necessarily the selected index). This particular bug was happening because the focusIndex was being accessed without making sure it is valid (>=0 && < tabPane.getTabCount()). This fix does the following: . focusIndex is now reset when a tab is removed. . When the selection changes the focusIndex is immediately reset to the selected index. . Checking to make sure focusIndex is valid and tabPane has been layed out before asking for component bounds. ###@###.### 2004-08-24 Here's the summary of changes: . Focus index is set to -1 at installUI time. . Focus index is set to selected index when it's on last tab and last tab is removed. . Focus index is set to selected index when selection changes. . Focus index is set to selected index on focus gain. Additionally the mouse handling logic was broke as part of introducing the focus index, it too has been reverted to what it was: . clicking on unselected tab changes selection, but not focus. . clicking on selected tab gives focus to tabbed pane. NOTE: this isn't quite right either, but it's at least what we have always done. Refer to 5092589 for details on what we should be doing. ###@###.### 2004-08-26
26-08-2004