Placing Components on Tabs


by John Zukowski

The JTabbedPane component is a special Swing container that accepts components to be placed within a panel for each tab. Select a tab to see that tab's components. Technically speaking, one component is associated with each tab. However, that component is typically a panel that contains others. Identification for each tab is done with title text and an icon, settable per tab. The first Core Java Technologies Tech Tip to discuss the JTabbedPane component was published in July 2001, with a simple introductory tip.

The methods of JTabbedPane to support the use of components on tabs are as follows:

  • public void setTabComponentAt(int index, Component component)
  • public Component getTabComponentAt(int index)
  • public int indexOfTabComponent(Component tabComponent)

The first method associates the component with a tab; the second gets it back; and the last one tells you which tab is associated with the component, if any. Typically, you use only the first method, but the others are available.

To get started with the task at hand, it is helpful to have an Icon implementation that draws a little x on it. You could just use the letter x as the button label, but you should avoid that option. Typically, when a user sees an x in a box, this signals a command to close a window, so it serves as a good indicator for closing a tab.

class CloseIcon implements Icon {
  public void paintIcon(Component c, Graphics g, int x, int y) {
    g.setColor(Color.RED);
    g.drawLine(6, 6, getIconWidth() - 7, getIconHeight() - 7);
    g.drawLine(getIconWidth() - 7, 6, 6, getIconHeight() - 7);
  }
  public int getIconWidth() {
    return 17;
  }
  public int getIconHeight() {
    return 17;
  }
}

Before creating the special tab component, let's put together the program's framework, one that creates a frame with a JTabbedPane on it and adds a number of tabs:

import java.awt.\*;
import java.awt.event.\*;
import javax.swing.\*;

public class CloseTabs {
  public static void main(String args[]) {
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("JTabbedPane");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTabbedPane jtp = new JTabbedPane();
        frame.add(jtp, BorderLayout.CENTER);
        for (int i=0; i<5; i++) {
          JButton button = new JButton("Card " + i);
          jtp.add("Btn " + i, button);
          // new CloseTabButton(jtp, i);
        }
        frame.setSize(400, 200);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}

This program creates five tabs, each with a JButton on it. The tab title is "Btn" followed by the tab position.

The program will run fine without doing anything else, but it doesn't have the close button on each tab. To add a close button to the tab, you need to retain the tab's title text and icon, while adding a button with the CloseIcon previously shown. (The example does not use the tab's icon, but the class definition includes one so that it can be reused beyond this example.) As the final part of the definition, you need an ActionListener for the button to handle when it is pressed, so that when the user presses the button, the tab is removed from the pane.

class CloseTabButton extends JPanel implements ActionListener {
  private JTabbedPane pane;
  public CloseTabButton(JTabbedPane pane, int index) {
    this.pane = pane;
    setOpaque(false);
    add(new JLabel(
        pane.getTitleAt(index),
        pane.getIconAt(index),
        JLabel.LEFT));
    Icon closeIcon = new CloseIcon();
    JButton btClose = new JButton(closeIcon);
    btClose.setPreferredSize(new Dimension(
        closeIcon.getIconWidth(), closeIcon.getIconHeight()));
    add(btClose);
    btClose.addActionListener(this);
    pane.setTabComponentAt(index, this);
  }
  public void actionPerformed(ActionEvent e) {
    int i = pane.indexOfTabComponent(this);
    if (i != -1) {
      pane.remove(i);
    }
  }
}

You can now reuse the CloseTabButton in your own tabbed panes.

For more information on the use of tabbed panes, see the How to Use Tabbed Panes lesson in The Java Tutorial.

Comments:

Hi thr ,
When I tried adding a JPanel object which contains String like "Tab1", "Tab2" and so on. The JPanel looks to be center aligned in the Tab component on top. Since, on either of the custom JPanel object, I see the blue shade. Are there anyway to stretch the JPanel object so that the shades are not visible ??Later, I found that setOpaque does the trick but when the Panel background is set to green or black , it looks ugly ...

Posted by Sasi on January 21, 2008 at 06:53 PM PST #

Post a Comment:
Comments are closed for this entry.
About

John O'Conner

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today