问题
Im adding and removing tabs in JTabbedPane dynamically. Code:
//Method which adds new tab
private void addTab(String title, MainPanel panel) {
tabbed.addTab(title, panel);
int index = tabbed.indexOfComponent(panel);
JPanel tabPanel = new JPanel();
tabPanel.setOpaque(false);
tabPanel.add(panel.getLabel());
JButton closeButton = new JButton(new CloseTabAc(index));
tabPanel.add(closeButton);
panel.getLabel().setText(title);
tabbed.setTabComponentAt(index, tabPanel);
tabbed.setSelectedIndex(index);
currentPanel = panel;
}
//Action to close tab
private class CloseTabAc extends AbstractAction {
private int tabNum;
CloseTabAc(int tabNum) {
putValue(Action.NAME, "x");
this.tabNum = tabNum;
}
@Override
public void actionPerformed(ActionEvent ev) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MainPanel panel = (MainPanel) tabbed.getComponentAt(tabNum);
tabbed.remove(tabNum);
}
});
}
}
So this is the code. When switching, removing tabs I get this error:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
at java.util.ArrayList.rangeCheck(ArrayList.java:604)
at java.util.ArrayList.get(ArrayList.java:382)
at javax.swing.JTabbedPane.getComponentAt(JTabbedPane.java:1224)
at jnotepad.MainFrame$CloseTabAc$1.run(MainFrame.java:247)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
...
Im trying to solve it few days but I dont see whats wrong. The only I saw this error occurs in situation when I open few tabs and close them randomly. So eg. I open 3 tabs: 1, 2 and 3. If I close them in order: 3, 2, 1 I get exception but everything close. But when I try to close them in order: 3, 1, 2 then 3 will close but on 1 exception will be thrown and it wont close now or then. So please help me solve my problem.
EDIT: I modified my code according to Jean's solution and now I get following exception:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:371)
at java.util.ArrayList.get(ArrayList.java:384)
at javax.swing.JTabbedPane.getComponentAt(JTabbedPane.java:1224)
at jnotepad.MainFrame$ChangeHandler.stateChanged(MainFrame.java:228)
at javax.swing.JTabbedPane.fireStateChanged(JTabbedPane.java:416)
at javax.swing.JTabbedPane$ModelListener.stateChanged(JTabbedPane.java:270)
...
Looks exception is in line 228. It's my stateChanged listener:
private class ChangeHandler implements ChangeListener {
@Override
public void stateChanged(ChangeEvent ev) {
currentPanel = (MainPanel) tabbed.getComponentAt(tabbed.getSelectedIndex());
}
}
Every tab has MainPanel instance in it. When another tab is selected I get this panel and set is as currentPanel in MainFrame. This exception doesnt break my GUI as previous one but Id like to get rid of it.
回答1:
If you have three tabs
| tab 0 | tab 1 | tab 2 |
if you remove tab 1, tab 2 index will be 1. That's why you get a IndexOutOfBoundsException
.
Pass a reference to the tab item, not its index on the tabbed pane, to the listener.
来源:https://stackoverflow.com/questions/15312252/jtabbedpane-arrayindexoutofboundsexception