Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TabbedPane closable tabs #193

Merged
merged 5 commits into from
Oct 22, 2020
Merged

TabbedPane closable tabs #193

merged 5 commits into from
Oct 22, 2020

Conversation

DevCharly
Copy link
Collaborator

@DevCharly DevCharly commented Oct 20, 2020

This PR introduces support for closable tabs.

image

Set client property JTabbedPane.tabClosable to true on a JTabbedPane to enable closing tabs.
You also have to provide a callback in client property JTabbedPane.tabCloseCallback that is responsible for closing the tab.

myTabbedPane.putClientProperty( "JTabbedPane.tabClosable", true );
myTabbedPane.putClientProperty( "JTabbedPane.tabCloseCallback",
    (java.util.function.BiConsumer<JTabbedPane, Integer>) (tabbedPane, tabIndex) -> {
        // close tab here
        tabbedPane.removeTabAt( tabIndex );
    } );

If you do not need the tabbed pane in the callback, it is possible to use a java.util.function.IntConsumer:

myTabbedPane.putClientProperty( "JTabbedPane.tabCloseCallback",
    (java.util.function.IntConsumer) tabIndex -> {
        // close tab here
        myTabbedPane.removeTabAt( tabIndex );
    } );

To show a tooltip if the mouse is over the close button, set the client property JTabbedPane.tabCloseToolTipText:

myTabbedPane.putClientProperty( "JTabbedPane.tabCloseToolTipText", "Close" );

grafik

You can set the three client properties also on single tabs. E.g. if not all tabs should be closeable. Or if only some tabs should be closable.

Component c = tabbedPane.getComponentAt( 1 );
((JComponent)c).putClientProperty( "JTabbedPane.tabClosable", false );

The style of the close button can be changed via UI properties. Here are the defaults for light themes:

TabbedPane.closeSize=16,16
TabbedPane.closeArc=4
TabbedPane.closeCrossPlainSize={float}7.5
TabbedPane.closeCrossFilledSize=$TabbedPane.closeCrossPlainSize
TabbedPane.closeCrossLineWidth={float}1

TabbedPane.closeBackground=null
TabbedPane.closeForeground=@disabledText
TabbedPane.closeHoverBackground=darken($TabbedPane.hoverColor,10%)
TabbedPane.closeHoverForeground=@foreground
TabbedPane.closePressedBackground=darken($TabbedPane.hoverColor,15%)
TabbedPane.closePressedForeground=$TabbedPane.closeHoverForeground

If you prefer circle close buttons, set arc to a large value and make filled cross smaller:

UIManager.put( "TabbedPane.closeArc", 999 );
UIManager.put( "TabbedPane.closeCrossFilledSize", 5.5f );

image

If you don't want a filled button on hover, but change cross color to red, try:

UIManager.put( "TabbedPane.closeHoverForeground", Color.red );
UIManager.put( "TabbedPane.closePressedForeground", Color.red );
UIManager.getLookAndFeelDefaults().put( "TabbedPane.closeHoverBackground", null );

image

This is part of TabbedPane improvements as discussed in issue #40 (comment) and #31.

CC @Gaarco @swordmaster2k

@DevCharly DevCharly added this to the 0.44 milestone Oct 20, 2020
@DevCharly DevCharly changed the title Tabbedpane closable tabs TabbedPane closable tabs Oct 20, 2020
@DevCharly DevCharly mentioned this pull request Oct 20, 2020
@DevCharly DevCharly merged commit 717ab95 into master Oct 22, 2020
@DevCharly DevCharly deleted the tabbedpane-closable-tabs branch October 22, 2020 22:23
DevCharly added a commit that referenced this pull request Oct 26, 2020
@Chrriis
Copy link
Contributor

Chrriis commented Apr 8, 2021

I tried to replace a home-made version of closable icons, so I naively removed the "close" component from the tab component and set the property instead. This did not work because I was acting on the tab component (cf. getTabComponentAt(index)) while the properties seem to have to be set on the component placed in the tab.

I think transition would be much easier if FlatLaf was also checking if a tab component is defined and read the properties from there first, then fallback on the component in the tab or the tabbed pane. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants