简体   繁体   English

JTabbedPane-具有关闭按钮参考的选项卡

[英]JTabbedPane - tab with close button reference

I want to build a tabbed interface in JAVA, with close button on each tab. 我想在JAVA中建立一个带标签的界面,每个标签上都带有关闭按钮。 For that I have used the following class: ButtonTabComponent 为此,我使用了以下类: ButtonTabComponent

I have a button on my GUI which creates a new tab. 我的GUI上有一个按钮,用于创建新标签。 Let's say I press the New Tab button 4 times, therefore 4 tabs are created: 假设我按了“新标签”按钮4次,因此创建了4个标签:

| | tab 0 | 标签0 | tab 1 | 标签1 | tab 2 | 标签2 | tab 3 | 标签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: 现在,我决定要关闭选项卡1并出现问题,当我关闭中间选项卡时,所有索引都重新排序-这意味着:

| | tab 0 | 标签0 | tab 2 | 标签2 | tab 3 | 标签3 | (tab 2 will have index 1) (选项卡2的索引为1)

If I try now to create a new tab, the tab is created but new tab: 如果现在尝试创建一个新选项卡,则会创建该选项卡,但会创建新的选项卡:

| | tab 0 | 标签0 | tab 2 | 标签2 | tab 3 | 标签3 | tab 1| 标签1 | (tab 1 has no close button) (选项卡1没有关闭按钮)

If I click again New Tab, I get: 如果再次单击“新建选项卡”,则会得到:

| | tab 0 | 标签0 | tab 2 | 标签2 | tab 3 | 标签3 | tab 1 | 标签1 | tab 4 | 标签4 | (tab 4 is fine, it has a close button) (选项卡4很好,它有一个关闭按钮)

Now I decide to close tab 2 and I get: 现在,我决定关闭选项卡2,然后得到:

| | tab 0 | 标签0 | tab 3 | 标签3 | tab 1| 标签1 | tab 4| 标签4 | (tab 3 will now have index 1) (选项卡3现在将具有索引1)

If I create a new tab: 如果我创建一个新标签:

| | tab 0 | 标签0 | tab 3 | 标签3 | tab 1| 标签1 | tab 4| 标签4 | tab 1 | 标签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: 我相信这是由索引引起的,我在stackoverflow上读了一个类似的问题: stackoverflow.com/questions/15312252/jtabbedpane-arrayindexoutofboundsexception ,可能的解决方案是:

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. 您不想将按钮添加到选项卡索引PanelCounter而是添加到刚刚创建的按钮中。 Its index can be obtained using getTabCount() , which of course at this point is one too high, hence: 可以使用getTabCount()获得它的索引,这当然是太高了,因此:

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. 在actionPerformed方法中。

Here I am creating JTabbedPane tabs, with a close button for each tab. 在这里,我正在创建JTabbedPane选项卡,每个选项卡都有一个关闭按钮。 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM