我想在JAVA中构建一个标签式界面,每个标签上都有关闭按钮。为此,我使用了以下课程:ButtonTabComponent
我的GUI上有一个按钮,可以创建一个新选项卡。假设我按下“新标签”按钮4次,因此创建了4个标签:
|标签0 |选项卡1 |标签2 |选项卡3 | (每个选项卡包含关闭按钮)
现在,我决定关闭选项卡1并出现问题,当我关闭中间选项卡时,所有索引都会重新排序 - 这意味着:
|标签0 |标签2 |选项卡3 | (选项卡2将具有索引1)
如果我现在尝试创建新标签,则会创建标签但新标签:
|标签0 |标签2 |标签3 |选项卡1 | (选项卡1没有关闭按钮)
如果我再次点击新标签,我会得到:
|标签0 |标签2 |标签3 |选项卡1 |选项卡4 | (标签4很好,它有一个关闭按钮)
现在我决定关闭标签2,然后我得到:
|标签0 |标签3 |选项卡1 |选项卡4 | (选项卡3现在将具有索引1)
如果我创建一个新标签:
|标签0 |标签3 |选项卡1 |标签4 |选项卡1 | (最后一个标签再次没有关闭按钮)。
我认为这是由索引引起的,我在类似的问题中读到,在stackoverflow:stackoverflow.com/questions/15312252/jtabbedpane-arrayindexoutofboundsexception,可能的解决方案是:
将对选项卡项的引用(而不是选项卡式窗格上的索引)传递给侦听器。
我不知道该怎么做。如果有人有任何暗示,我会真的非常感激。 我需要为每个选项卡保留一个可靠的引用,因为每个选项卡将打开一个文件,它将能够保存到文件,显然选项卡索引不可靠。
编辑:我在代码中添加新标签的方式是:
...//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
}
答案 0 :(得分:1)
错误在于通话
pane.setTabComponentAt(PanelCounter, new ButtonTabComponent(pane, this));
您不希望将按钮添加到选项卡索引PanelCounter
,而是添加到刚创建的按钮。它的索引可以使用getTabCount()
获得,当然在这一点上太高了,因此:
pane.setTabComponentAt(pane.getTabCount()-1, new ButtonTabComponent(pane, this));
答案 1 :(得分:0)
我正在检查您的代码,我可以使用
完成pane.remove(pane.getSelectedComponent());
在actionPerformed方法中。
答案 2 :(得分:0)
这里我创建了JTabbedPane选项卡,每个选项卡都有一个关闭按钮。 单击关闭按钮时,仅关闭相应的选项卡。
//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;
}