Closable Tabs in a Tabbed Pane

Hi,

I am working on an application, where i need to have an "x" mark on the Tabs, clicking on which, i should be able to close the Tab. (Some what similar to the Tabbed pages we see in Eclipse)

This is Java 1.5 Application. Is there a way to add a button or an Icon to the Tab, and attach an action listener to it, in such a way that the tab page will be closed upon clicking on the button or icon?

Please Help.

thanks,

vani

[461 byte] By [vani_ha] at [2007-10-3 2:45:07]
# 1
Sure, search the forum. This question has been asked and answered before. I forget the keywords I used but something like "jtabbedpane close icon" should get you started.
camickra at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 2

Here is one possible solution that I adapted from a posting on the Internet by adding logic to support getting the user to confirm the close.

Use this code when you add the tab:tabbedPane.addTab(theTitle, new CloseTabIcon(), theComponent, tooltip);

And add this class to your application:import java.awt.Component;

import java.awt.Graphics;

import java.awt.Rectangle;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent;

import javax.swing.Icon;

import javax.swing.ImageIcon;

import javax.swing.JOptionPane;

import javax.swing.JTabbedPane;

/**

* This class encapsulates an icon that can be added to the selector tab of a JTabbedPane to allow

* clicks upon it to close its owning tab.

*

* Created on 19/06/2006 by Tim Ryan

*/

public class CloseTabIcon implements Icon {

private final Icon icon;

private JTabbedPane tabbedPane = null;

private transient Rectangle position = null;

/**

* Creates a new instance of CloseTabIcon.

*/

public CloseTabIcon() {

this.icon = new ImageIcon(CloseTabIcon.class.getResource("images/CloseTab.gif"));

}

/**

* when painting, remember last position painted so we can see if the user clicked on the icon.

*/

public void paintIcon(Component component, Graphics g, int x, int y) {

// Lazily create a link to the owning JTabbedPane and attach a listener to it, so clicks on the

// selector tab can be intercepted by this code.

if (tabbedPane == null) {

tabbedPane = (JTabbedPane) component;

tabbedPane.addMouseListener(new MouseAdapter() {

@Override

public void mouseReleased(MouseEvent e) {

// asking for isConsumed is *very* important, otherwise more than one tab might get closed!

if (! e.isConsumed() && position.contains(e.getX(), e.getY())) {

Macro macro = (Macro) tabbedPane.getSelectedComponent();

boolean close = true;

if (macro.isModified()) {

int result = JOptionPane.showConfirmDialog(PlayAct.getInstance().getFrame(), "The macro " + macro.getTitle()

+ " is modified but unsaved.\nDo you wish to save before closing?", "CONFIRM",

JOptionPane.YES_NO_CANCEL_OPTION);

if (result == JOptionPane.YES_OPTION) {

macro.save();

} else if (result == JOptionPane.CANCEL_OPTION) {

close = false;

}

}

if (close) {

tabbedPane.remove(macro);

}

e.consume();

}

}

});

}

position = new Rectangle(x, y, getIconWidth(), getIconHeight());

icon.paintIcon(component, g, x, y);

}

/**

* just delegate

*/

public int getIconWidth() {

return icon.getIconWidth();

}

/**

* just delegate

*/

public int getIconHeight() {

return icon.getIconHeight();

}

}

TimRyanNZa at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 3

Substance LAF [1] provides easily configurable closable tabs [2] with full support for RTL applications and vetoable close listeners [3]

[1] https://substance.dev.java.net

[2] http://weblogs.java.net/blog/kirillcool/archive/2005/10/spicing_up_your.html

[3] http://weblogs.java.net/blog/kirillcool/archive/2005/12/spicing_up_your_1.html

kirillga at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 4

Hi I searched the forum and found some solutions.

But none of them work for the Scrollable Tab layout and when the tabs are at the BOTTOM. For my application, these 2 are a must.

So, has someone solved this problem?

I tried a lot to change the code given in the forum to make it work for the Bottom tabs with scroll layout... something is not right and i dont see the UI.

please help...

vani

vani_ha at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 5
Sorry, i cant use the substance.jar as the jar file is way too big for the application and we need the platform default look and feel.vani
vani_ha at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 6

> But none of them work for the Scrollable Tab layout and when the tabs are at the BOTTOM.

I fail to see why this makes a difference. An icon or custom painting is added to the tab. It makes no difference whether the tabs are displayed at the top, bottom, left or right. Keep searching.

camickra at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 7

No camickr

For whatever reason, the mouse clicks on the icon are not recognised if the scroll tab layout is used and when the tabs are laid out at the bottom

I searched all the possibilities still could not find a solution

If you know any specific solution that worked for you please post it.

thanks

vani

vani_ha at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 8
http://forum.java.sun.com/thread.jspa?forumID=57&threadID=611667 http://forum.java.sun.com/thread.jspa?forumID=257&threadID=453521
camickra at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 9

> But none of them work for the Scrollable Tab layout and when the tabs are at the BOTTOM

it's fairly simple to get this to work when at the bottom, the problem is with both

wrap and scroll layouts (affects TOP the same way)

the icon rectangle coords, when in a wrap/scroll layout, do not match the

clickable area coords available to the mouse.

to understand, use any of the code you have found, adjust for say 12 tabs,

set them to the TOP. Do not use wrap or scroll layout. run the program, drag

the frame wide enough to display the 12 tabs. Now click any of the tabs and they

will all be closeable.

change the code to a scroll layout, recompile and run again. You can close

the first couple (because the screen coords match), but the rest do not close.

when you run the program, immediately scroll a few tabs to the right, click one,

it will not close, but the tab (0,1,2 etc) that was in that position on opening will close.

if you change to the bottom, you have to modify the rect coords to increase y

by the tabpane's preferredSize.height and deduct the tabarea rect.height.

I would say it is certainly possible to achieve what you want, but it will take a

lot of work/code to get the icon's coords to match me.getX() and me.getY().

It might be a whole lot easier if you could use java 1.6, where I believe tabpanes

can now have components in the tab area, if so, a JButton should do exactly what you want

Michael_Dunna at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 10

Yea, i saw that they have fixed it in Mustang by adding a method

setTabComponentAt(index, comp)

But, i clearly dont know when Mustang will be out.

It is still in Beta, Also, i dont know after Mustang comes out, whether we will have enough time to use that and test our product before our release date.

So i want to get this feature working in JAva 1.5 itself.

thanks,

vani

vani_ha at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...
# 11
Look at the CloseableTabbedPane class in the http://swingutil.dev.java.net project. It's possible to do this with a UI override.
greggwona at 2007-7-14 20:33:43 > top of Java-index,Desktop,Core GUI APIs...