Adding tab close buttons to a JTabbedPane in Java Swing

Any Java developer who works with tabbed panes in their applications knows that the basic JTabbedPane doesn’t provide out-of-the-box functionality to close tabs. Ten years ago that was fine, but these days we expect to be able to click little buttons on our tabs and close them. Until Java 6, it just wasn’t possible to add buttons to tabs. These days, we have the ability to add our own customizations to the tab via the setTabComponentAt method.

There are several examples of how to do this on the web, but most of them show the basics of adding a button to a tab and leave it at that.

I wanted to have an easy way to add the  to any tab, while still allowing a custom tab icon and text, and I wanted the close-tab button to support rollover effects, so that it is only red when you hover over it.

Here a short sample program that demonstrates using a simple method to decorate tabs with little close buttons.

Getting the Necessary Pieces

I did an image search for a suitable icon and found a nice little 11×11 red close-tab icon at this site, from the open source Notepad++ program. I went to Icon Finder for the example Edit Page icon.

In order to easily render a grayscale version of the button icon, for rollover, I used the RGBGrayFilter utility class from JGoodies.

This example also uses the popular Plastic look and feel, so you will need to download both JGoodies Common and JGoodies Looks from their download page.

Note that the JGoodies stuff is optional—I used it for the look and for the grayscale utility, but you can easily just provide two different versions of the icon for your tab button.

The Code 

How it Works

The static method addClosableTab will add a panel (or other component) to a JTabbedPane with a “close button” tab containing an icon and a text label.

The parameters are final, so that they can be accessed from within the anonymous classes used for listeners.

Lines 40-42 add the payload to the tabbed pane, without any label.

Lines 44-53 create a small panel that will contain everything shown on the tab itself. This area is circled in red below.

Lines 55-68 create the close-tab button.

Lines 70-76 put all the bits together in the tab panel.

Line 79 puts the panel into the tab using the aforementioned setComponentAt method.

Lines 81-90 add a listener to the button that will close the tab when it is clicked.

Line 91 brings the new tab to the front.

Optional bonus…

Lines 95-116 add a keystroke handler so you can close the tab with Control-W.

Additional Notes

As I mentioned earlier, I didn’t want to have to make my own “unselected” version of the button, since I might be trying different variations of buttons. Fortunately, JGoodies provides a handy-dandy utility class that they use to make gray icons for their toolbars. In line 62 I use the RGBGrayFilter class to make a grayed-out version of the button icon.

The actual placement of the labels on the tab depends heavily on the look and feel you are using. I found that I had to tweak the settings of the tab panel’s layout and border in order for it to look nice when using the Plastic look and feel. If I were using a different look and feel, I would probably have to tweak the borders.

I noticed that when a tab is selected, its label is raised up a few pixels. Without tweaking borders and opacity, this resulted in the tab panel being painted over the top edge of the tab, resulting in behavior like this:

Similar strange behavior happens if you omit some of the other border tweaks.

The action listener I use is quite simplistic. In a real application, you probably want to ask the content of the tab if it can be closed, to make sure the user doesn’t lose any changes.

Some apps, like Safari, hide the button altogether until the mouse hovers over it. To achieve this, simply use a blank icon for the normal (non rollover) button icon.

Finally, if you use the Control-W tab close hot key, note that some components (I’m looking at you, JTable), swallow keystrokes in ways that make it difficult for higher components to see the keystroke. In addition, if you run your app on a Mac, you would probably want to map the close command to Command-W instead of Control-W.

I hope this helps somebody!

 

8 Responses to “Adding tab close buttons to a JTabbedPane in Java Swing”

  1. Rajakrishna Reddy writes:

    Really very nice post … !!! Good help!!

    But one thing … Why is it not properly working with JTabbedPane#SCROLL_TAB_LAYOUT option !!????

  2. Chp writes:

    Extremely useful..many thanks for posting!!!

  3. Renata writes:

    Thank you a lot. Really well explained! It has helped a lot!

  4. Maduka writes:

    Thank you…
    Try to add more examle for JavaSE Plz….

  5. Moosh writes:

    Great! Helped me a lot. thanx

  6. Orgenetnom writes:

    Hey! Can someone figure out a way to do it from within the tabbedpane class? I think that would be very interesting, don’t you?

  7. Orgenetnom writes:

    Very nice and useful example, by the way.

  8. Michel Tank writes:

    Thank! Very good!

Leave a Reply