Exception Removing Tabs from JTabbedPane



While perusing a newsgroup I found a simple subclass of JTabbedPane that
includes an X icon for deleting tabs. However, when I tried it I
periodically get ArrayIndexOutOfBounds exceptions on the event thread when
deleting tabs - not sure why. Stack trace and code below.

Thanks in Advance,
Mike

Exception in thread "AWT-EventQueue-0"
java.lang.ArrayIndexOutOfBoundsException: 0

at javax.swing.plaf.basic.BasicTabbedPaneUI.getTabBounds(Unknown Source)

at javax.swing.plaf.basic.BasicTabbedPaneUI.getTabBounds(Unknown Source)

at
com.sun.java.swing.plaf.windows.WindowsTabbedPaneUI.setRolloverTab(Unknown
Source)

at
javax.swing.plaf.basic.BasicTabbedPaneUI$TabbedPaneLayout.layoutContainer(Unknown
Source)

at java.awt.Container.layout(Unknown Source)

at java.awt.Container.doLayout(Unknown Source)

at java.awt.Container.validateTree(Unknown Source)

at java.awt.Container.validateTree(Unknown Source)

at java.awt.Container.validate(Unknown Source)

at javax.swing.RepaintManager.validateInvalidComponents(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.pumpOneEventForHierarchy(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)

---------------------------

public class JTabbedPaneWithCloseIcons extends JTabbedPane implements
MouseListener {
public JTabbedPaneWithCloseIcons() {
super();
addMouseListener(this);
}

public void addTab(String title, Component component) {
this.addTab(title, component, null);
}

public void addTab(String title, Component component, Icon extraIcon) {
super.addTab(title, new CloseTabIcon(extraIcon), component);
}

public void addTab(String title, Icon extraIcon, Component component,
String tip) {
super.addTab(title, new CloseTabIcon(extraIcon), component, tip);
}

public void insertTab(String title, Icon extraIcon, Component component,
String tip, int index) {
super.insertTab(title, extraIcon, component, tip, index);
}

public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {
final int tabNumber=getUI().tabForCoordinate(this, e.getX(), e.getY());
if (tabNumber < 0) return;
Rectangle rect=((CloseTabIcon)getIconAt(tabNumber)).getBounds();
if (rect.contains(e.getX(), e.getY())) {
//the tab is being closed
this.removeTabAt(tabNumber);
}
}
}

/**
* The class which generates the 'X' icon for the tabs. The constructor
* accepts an icon which is extra to the 'X' icon, so you can have tabs
* like in JBuilder. This value is null if no extra icon is required.
*/
class CloseTabIcon implements Icon {
private int x_pos;
private int y_pos;
private int width;
private int height;
private Icon fileIcon;

public CloseTabIcon(Icon fileIcon) {
this.fileIcon=fileIcon;
width=16;
height=16;
}

public void paintIcon(Component c, Graphics g, int x, int y) {
this.x_pos=x;
this.y_pos=y;

Color col=g.getColor();

g.setColor(Color.black);
int y_p=y+2;
g.drawLine(x+1, y_p, x+12, y_p);
g.drawLine(x+1, y_p+13, x+12, y_p+13);
g.drawLine(x, y_p+1, x, y_p+12);
g.drawLine(x+13, y_p+1, x+13, y_p+12);
g.drawLine(x+3, y_p+3, x+10, y_p+10);
g.drawLine(x+3, y_p+4, x+9, y_p+10);
g.drawLine(x+4, y_p+3, x+10, y_p+9);
g.drawLine(x+10, y_p+3, x+3, y_p+10);
g.drawLine(x+10, y_p+4, x+4, y_p+10);
g.drawLine(x+9, y_p+3, x+3, y_p+9);
g.setColor(col);
if (fileIcon != null) {
fileIcon.paintIcon(c, g, x+width, y_p);
}
}

public int getIconWidth() {
return width + (fileIcon != null? fileIcon.getIconWidth() : 0);
}

public int getIconHeight() {
return height;
}

public Rectangle getBounds() {
return new Rectangle(x_pos, y_pos, width, height);
}
}



.



Relevant Pages

  • Re: Java API sound
    ... I was using mixer but port is better solution; ... private void CreateInterface ... public void actionPerformed{ ... int d = -1; ...
    (comp.lang.java.programmer)
  • Re: mehrfach unterstreichen =?ISO-8859-1?Q?m=F6glich=3F?=
    ... private void init() { ... private void fill(DefaultMutableTreeNode node, int depth) { ... public void changedUpdate{ ... return vGap; ...
    (de.comp.lang.java)
  • JFrame Resize Issues (Redux)
    ... However, when the LookAndFeel is set, Java's Window Manager ... public int OffSetX = 0; ... private Rectangle positRectangle; ... public void componentHidden{ ...
    (comp.lang.java.programmer)
  • Re: mehrfach unterstreichen =?ISO-8859-1?Q?m=F6glich=3F?=
    ... */ public class FlowDOMView extends JPanel {private DefaultTreeModel model = null; ... private void fill(DefaultMutableTreeNode node, int depth) { ... public void changedUpdate{ ... return vGap; ...
    (de.comp.lang.java)
  • Re: custom table cell focus traversal
    ... //the focus to the first textfield. ... public void makeTextBoxes{ ... int column) { ... ConnectionTableModel ctm = table.getModel; ...
    (comp.lang.java.gui)