I want to build a tabbed interface in JAVA, with close button on each tab. For that I have used the following class: ButtonTabComponent
I have a button on my GUI which creates a new tab. Let's say I press the New Tab button 4 times, therefore 4 tabs are created:
| tab 0 | tab 1 | tab 2 | tab 3 | (each tab contain a close button)
Now, I decide I want to close tab 1 and the problem appears, when I am closing a middle tab, all indexes are reordered - meaning that:
| tab 0 | tab 2 | tab 3 | (tab 2 will have index 1)
If I try now to create a new tab, the tab is created but new tab:
| tab 0 | tab 2 | tab 3 | tab 1| (tab 1 has no close button)
If I click again New Tab, I get:
| tab 0 | tab 2 | tab 3 | tab 1 | tab 4 | (tab 4 is fine, it has a close button)
Now I decide to close tab 2 and I get:
| tab 0 | tab 3 | tab 1| tab 4| (tab 3 will now have index 1)
If I create a new tab:
| tab 0 | tab 3 | tab 1| tab 4| tab 1 | (the last tab again has no close button).
I believe that this is caused by the index and I read in a similar question, here on stackoverflow : stackoverflow.com/questions/15312252/jtabbedpane-arrayindexoutofboundsexception that a possible solution would be to:
Pass a reference to the tab item, not its index on the tabbed pane, to the listener.
I am not sure how to do that. If anyone has any hint, I would really, really appreciate. I need to keep a solid reference for each tab, as each tab will open a file and it will have the ability to save to a file and obviously the tab index is not reliable.
EDIT: The way I add a new tab in my code is:
...//main class
private final JTabbedPane pane = new JTabbedPane();
//I am using an array to store the tabs created
//I initialize the array with false. the idea was that when a new tab get created, one item in the array
//gets the true value. when the tab is closed, the array item (based on the index) is set back to false
arrTabList = new boolean[10];
for(int i=0; i<10; i++){
arrTabList[i] = false;
}
...
public void newFile() //this function opens a new tab
{
//parse the array to check the first item with false status
for(int i=0; i<10; i++){
if(!arrTabList[i]) {
System.out.println("false");
PanelCounter = i;
break;
}
}
newTab t = new newTab(); //object which contains the tab content (a bunch of graphical components, input fields mostly)
pane.add("New Entry" + PanelCounter, t.createContentPane()); //adds the new tab to the main window
pane.setTabComponentAt(PanelCounter, new ButtonTabComponent(pane, this));
arrTabList[PanelCounter] = true; //sets the item array to true
}
//when a tab is closed, this function is called in the listener:
public void decreaseCounter(int i)
{
arrTabList[i] = false; //sets the item array back to false
}
The error lies in the call
pane.setTabComponentAt(PanelCounter, new ButtonTabComponent(pane, this));
You don't want to add the button to the tab index PanelCounter
but to the one just created. Its index can be obtained using getTabCount()
, which of course at this point is one too high, hence:
pane.setTabComponentAt(pane.getTabCount()-1, new ButtonTabComponent(pane, this));
I was checking your code and I could accomplish using
pane.remove(pane.getSelectedComponent());
in the actionPerformed method.
Here I am creating JTabbedPane tabs, with a close button for each tab. When the close button is clicked, only the respective tab closes.
//This is where a tab is created in some other function of same class
jtp.addTab("Create",new JPanel()); //jtp is a global JTabbedPane variable
int index = jtp.indexOfTab("Create");
jtp.setTabComponentAt(index,createTabHead("Create"));
public JPanel createTabHead(String title)
{
final String st=title;
JPanel pnlTab = new JPanel();
pnlTab.setLayout(new BoxLayout(pnlTab,BoxLayout.LINE_AXIS));
pnlTab.setOpaque(false);
JButton btnClose = new JButton("x");
JLabel lblTitle = new JLabel(title+" ");
btnClose.setBorderPainted(false);
btnClose.setOpaque(false);
btnClose.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int i;
for(i=0;i<=jtp.getTabCount()-1;i++)//To find current index of tab
{
if(st.equals(jtp.getTitleAt(i)))
break;
}
jtp.removeTabAt(i);
}
});
pnlTab.add(lblTitle);
pnlTab.add(btnClose);
return pnlTab;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.