How to add close button to a JTabbedPane Tab?
Asked Answered
L

7

33

I'm working in with a JTabbedPane, I need to add a close button in the tabs to close the current one.

I have been searching and as I understand I must extend from JPanel and add the close button as they say here But, is there a way to add the close buttons extending JTabbedPane or is there a easier way to do it?

Thanks in advance, I really appreciate your time and your help.

Languedoc answered 19/7, 2012 at 2:30 Comment(2)
This might be helpful - #10621130Speedy
Thanks i'm going to check it outLanguedoc
D
52

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...

Dorinedorion answered 19/7, 2012 at 2:51 Comment(4)
Thanks!!! it looks great. I'm going to check it at afternoon. I really appreciate your helpLanguedoc
That's try. If you read the code, the ActionListener is using the selected tab. You associate the tab component with the action listener, find the index and remove it insteadDorinedorion
Updated with additional exampleDorinedorion
See also this excellent(1) example (1) with a much higher ratio of screenshots of flying ponies (with guns). :)Doing
H
6

I found a tab example (from the java site) that appears to do that, at least in theirs. (Though I thought, when I tried it in the past, that it also closed the currently selected tab, though it works properly when you run their example, though I think when I updated it to work on a tabbed java notepad, it was closing the currently selected tab, though maybe I did it wrong.

http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java

Yes, my thing is working now! This WILL work for the actual tab, rather than the currently selected tab!

Handsaw answered 26/8, 2013 at 3:11 Comment(1)
Though, you should know that by doing so, it kind of ruins your ability to set tab icons. (Unless you wanna go and mess with the lower levels and look at the source code and do paintComponent() and all that fun stuff, I can't see a way around that issue.)Handsaw
C
2

Hopefully you have got the answer to your question. I want to give a link that was very useful for me.

JTabbedPane with a close button

Here is some code as well.

public static void createAndShowGUI()
{
    JFrame frame = new JFrame("Tabs");
    frame.setMinimumSize(new Dimension(500, 200));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTabbedPane tabbedPane = new JTabbedPane();

    JPanel panel = new JPanel();
    panel.setOpaque(false);
    tabbedPane.add(panel);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel), getTitlePanel(tabbedPane, panel, "Tab1"));

    JPanel panel1 = new JPanel();
    panel1.setOpaque(false);
    tabbedPane.add(panel1);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel1), getTitlePanel(tabbedPane, panel1, "Tab2"));

    JPanel panel2 = new JPanel();
    panel2.setOpaque(false);
    tabbedPane.add(panel2);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel2), getTitlePanel(tabbedPane, panel2, "Tab3"));

    JPanel panel3 = new JPanel();
    panel3.setOpaque(false);
    tabbedPane.add(panel3);
    tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(panel3), getTitlePanel(tabbedPane, panel3, "Tab4"));

    frame.add(tabbedPane);

    // Display the window.
    frame.pack();
    frame.setVisible(true);
}
Cur answered 16/2, 2014 at 11:27 Comment(0)
E
1

I made some changes in the code of oracle.

http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/uiswing/examples/components/TabComponentsDemoProject/src/components/ButtonTabComponent.java

Giving the possibility to add an icon to the tab , plus the close tab button. Hope that helps.

public static void addTag(JTabbedPane tab, String title, Icon icon, int index){
     MouseListener close = new MouseAdapter() {

        @Override
        public void mouseClicked(MouseEvent e) {
            //your code to remove component
            //I use this way , because I use other methods of control than normal: tab.remove(int index);
        }

    };
    final ButtonClose buttonClose = new ButtonClose (title, icon, close );

    tab.setTabComponentAt(index, buttonClose);
    tab.validate();
    tab.setSelectedIndex(index);

}

public class ButtonClose extends JPanel {

public ButtonClose(final String title, Icon icon, MouseListener e) {
    JLabel ic = new JLabel(icon);
    ic.setSize(icone.getIconWidth(), icone.getIconHeight());

    JLabel text= new JLabel(title);
    text.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));

    ButtonTab button = new ButtonTab();
    button.addMouseListener(e);
    button.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));

    JPanel p = new JPanel();
    p.setSize(getWidth() - icone.getIconWidth(), 15);
    p.add(text);
    p.add(button);

    add(ic);
    add(p);
}

private class ButtonTab extends JButton {

    public ButtonTab() {
        int size = 13;
        setPreferredSize(new Dimension(size, size));
        setToolTipText("Close");

        setUI(new BasicButtonUI());

        setFocusable(false);
        setBorderPainted(false);

        addMouseListener(listener);
        setRolloverEnabled(true);
    }

    @Override
    public void updateUI() {
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();

        if (getModel().isPressed()) {
            g2.translate(1, 1);
        }
        g2.setStroke(new BasicStroke(2));
        g2.setColor(new Color(126, 118, 91));

        if (getModel().isRollover()) {
            g2.setColor(Color.WHITE);
        }

        int delta = 3;
        g2.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
        g2.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
        g2.dispose();
    }
}

private final MouseListener listener = new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        Component component = e.getComponent();
        if (component instanceof AbstractButton) {
            AbstractButton button = (AbstractButton) component;
            button.setContentAreaFilled(true);
            button.setBackground(new Color(215, 65, 35));
        }
    }

    @Override
    public void mouseExited(MouseEvent e) {
        Component component = e.getComponent();
        if (component instanceof AbstractButton) {
            AbstractButton button = (AbstractButton) component;
            button.setContentAreaFilled(false); //transparent
        }
    }
};

}

Edric answered 6/11, 2014 at 6:9 Comment(0)
T
1

Check out Peter-Swing here. It has a JClosableTabbedPane class in it, as well as many others.

When you download the jar file you can run it and have examples of all the classes.

Towpath answered 19/11, 2014 at 2:7 Comment(0)
F
1

You can have a JLabel named "x" and use the mouseListener

 private final JLabel l = new JLabel(); // this is the label for tabbedPane
 private final JLabel b = new JLabel("x");//Close Button
 if (closeable)
        {
            b.setToolTipText("Click to close");

            b.setOpaque(false);
            b.setBackground(Color.gray);

            b.addMouseListener(new MouseAdapter()
            {
                @Override
                public void mouseExited(MouseEvent e)
                {
                    b.setBorder(bordere);
                    b.setOpaque(false);
                }

                @Override
                public void mouseEntered(MouseEvent e)
                {
                    b.setBorder(borderl);
                }

                @Override
                public void mouseReleased(MouseEvent e)
                {
                    b.setOpaque(false);
                    b.repaint();

                    if (b.contains(e.getPoint()))
                    {
                        b.setBorder(borderl);

                        if (confirmTabClosing())
                        {
                            tab.remove(tabIndex());
                            if(tab.getTabCount() == 0)
                                spacialTabComponent.maximizeOrRestore.doClick();
                        }
                    }
                    else
                        b.setBorder(bordere);

                }

                @Override
                public void mousePressed(MouseEvent e)
                {
                    b.setOpaque(true);
                    b.repaint();
                }
            });

            b.setBorder(bordere);
            add(b, getLeftAlignedBothFilledGBC(1, 0, new Insets(0, 0, 0, 0), 0, 0));
        }



    }
Faxen answered 2/12, 2014 at 12:18 Comment(0)
M
1
jbCloseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int index = jtbMainTabbedPane.indexOfTabComponent(jbCloseButton);
                jtbMainTabbedPane.remove(index);
            }
});
Monumentalize answered 24/10, 2015 at 11:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.