Wednesday Jan 02, 2008
Wednesday Jan 02, 2008
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.
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 22, 2008 at 02:53 AM PST #