How to add close button to a JTabbedPane Tab?

Essentially, you’re going to need to supply a “renderer” for the tab. Take a look at JTabbedPane.setTabComponentAt(…) for more information.

The basic idea is to supply a component that will be laid out on the tab.

I typically create a JPanel, onto which I add a JLabel (for the title) and, depending on what I want to display, some kind of control that acts as the close action.

tabPane.addTab(title, tabBody);
int index = tabPane.indexOfTab(title);
JPanel pnlTab = new JPanel(new GridBagLayout());
pnlTab.setOpaque(false);
JLabel lblTitle = new JLabel(title);
JButton btnClose = new JButton("x");

GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;

pnlTab.add(lblTitle, gbc);

gbc.gridx++;
gbc.weightx = 0;
pnlTab.add(btnClose, gbc);

tabPane.setTabComponentAt(index, pnlTab);

btnClose.addActionListener(myCloseActionHandler);

Now somewhere else, I establish the action handler…

public class MyCloseActionHandler implements ActionListener {

    public void actionPerformed(ActionEvent evt) {

        Component selected = tabPane.getSelectedComponent();
        if (selected != null) {

            tabPane.remove(selected);
            // It would probably be worthwhile getting the source
            // casting it back to a JButton and removing
            // the action handler reference ;)

        }

    }

}

Now, you just as easily use any component you like and attach a mouse listener to it and monitor the mouse clicks…

Updated

The above example will only remove the currently active tab, there are a couple of ways to fix this.

The best is to probably provide some means for the action to find the tab it’s associated with…

public class MyCloseActionHandler implements ActionListener {

    private String tabName;

    public MyCloseActionHandler(String tabName) {
        this.tabName = tabName;
    }

    public String getTabName() {
        return tabName;
    }

    public void actionPerformed(ActionEvent evt) {

        int index = tabPane.indexOfTab(getTabName());
        if (index >= 0) {

            tabPane.removeTabAt(index);
            // It would probably be worthwhile getting the source
            // casting it back to a JButton and removing
            // the action handler reference ;)

        }

    }

}   

This uses the name of tab (as used with JTabbedPane#addTab) to find and then remove the tab and its associated component…

Leave a Comment