com.formdev.flatlaf.extras.components.FlatTabbedPane Maven / Gradle / Ivy
/*
* Copyright 2020 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Component;
import java.awt.Insets;
import java.util.function.BiConsumer;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
/**
* Subclass of {@link JTabbedPane} that provides easy access to FlatLaf specific client properties.
*
* @author Karl Tauber
*/
public class FlatTabbedPane
extends JTabbedPane
implements FlatComponentExtension
{
/**
* Returns whether separators are shown between tabs.
*/
public boolean isShowTabSeparators() {
return getClientPropertyBoolean( TABBED_PANE_SHOW_TAB_SEPARATORS, "TabbedPane.showTabSeparators" );
}
/**
* Specifies whether separators are shown between tabs.
*/
public void setShowTabSeparators( boolean showTabSeparators ) {
putClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
}
/**
* Returns whether the separator between tabs area and content area should be shown.
*/
public boolean isShowContentSeparators() {
return getClientPropertyBoolean( TABBED_PANE_SHOW_CONTENT_SEPARATOR, true );
}
/**
* Specifies whether the separator between tabs area and content area should be shown.
*/
public void setShowContentSeparators( boolean showContentSeparators ) {
putClientPropertyBoolean( TABBED_PANE_SHOW_CONTENT_SEPARATOR, showContentSeparators, true );
}
/**
* Returns whether a full border is painted around a tabbed pane.
*/
public boolean isHasFullBorder() {
return getClientPropertyBoolean( TABBED_PANE_HAS_FULL_BORDER, "TabbedPane.hasFullBorder" );
}
/**
* Specifies whether a full border is painted around a tabbed pane.
*/
public void setHasFullBorder( boolean hasFullBorder ) {
putClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder );
}
/**
* Returns whether the tab area should be hidden if it contains only one tab.
*/
public boolean isHideTabAreaWithOneTab() {
return getClientPropertyBoolean( TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, false );
}
/**
* Specifies whether the tab area should be hidden if it contains only one tab.
*/
public void setHideTabAreaWithOneTab( boolean hideTabAreaWithOneTab ) {
putClientPropertyBoolean( TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, hideTabAreaWithOneTab, false );
}
/**
* Returns the minimum width of a tab.
*/
public int getMinimumTabWidth() {
return getClientPropertyInt( TABBED_PANE_MINIMUM_TAB_WIDTH, "TabbedPane.minimumTabWidth" );
}
/**
* Specifies the minimum width of a tab.
*/
public void setMinimumTabWidth( int minimumTabWidth ) {
putClientProperty( TABBED_PANE_MINIMUM_TAB_WIDTH, (minimumTabWidth >= 0) ? minimumTabWidth : null );
}
/**
* Returns the minimum width of the tab at the given tab index.
*/
public int getMinimumTabWidth( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
return clientPropertyInt( c, TABBED_PANE_MINIMUM_TAB_WIDTH, 0 );
}
/**
* Specifies the minimum width of the tab at the given tab index.
*/
public void setMinimumTabWidth( int tabIndex, int minimumTabWidth ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_MINIMUM_TAB_WIDTH, (minimumTabWidth >= 0) ? minimumTabWidth : null );
}
/**
* Returns the maximum width of a tab.
*/
public int getMaximumTabWidth() {
return getClientPropertyInt( TABBED_PANE_MAXIMUM_TAB_WIDTH, "TabbedPane.maximumTabWidth" );
}
/**
* Specifies the maximum width of a tab.
*
* Applied only if tab does not have a custom tab component
* (see {@link javax.swing.JTabbedPane#setTabComponentAt(int, java.awt.Component)}).
*/
public void setMaximumTabWidth( int maximumTabWidth ) {
putClientProperty( TABBED_PANE_MAXIMUM_TAB_WIDTH, (maximumTabWidth >= 0) ? maximumTabWidth : null );
}
/**
* Returns the maximum width of the tab at the given tab index.
*/
public int getMaximumTabWidth( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
return clientPropertyInt( c, TABBED_PANE_MAXIMUM_TAB_WIDTH, 0 );
}
/**
* Specifies the maximum width of the tab at the given tab index.
*
* Applied only if tab does not have a custom tab component
* (see {@link javax.swing.JTabbedPane#setTabComponentAt(int, java.awt.Component)}).
*/
public void setMaximumTabWidth( int tabIndex, int maximumTabWidth ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_MAXIMUM_TAB_WIDTH, (maximumTabWidth >= 0) ? maximumTabWidth : null );
}
/**
* Returns the minimum height of a tab.
*/
public int getTabHeight() {
return getClientPropertyInt( TABBED_PANE_TAB_HEIGHT, "TabbedPane.tabHeight" );
}
/**
* Specifies the minimum height of a tab.
*
* @see #setTabInsets(Insets)
*/
public void setTabHeight( int tabHeight ) {
putClientProperty( TABBED_PANE_TAB_HEIGHT, (tabHeight >= 0) ? tabHeight : null );
}
/**
* Returns the insets of a tab.
*/
public Insets getTabInsets() {
return getClientPropertyInsets( TABBED_PANE_TAB_INSETS, "TabbedPane.tabInsets" );
}
/**
* Specifies the insets of a tab.
*
* @see #setTabHeight(int)
*/
public void setTabInsets( Insets tabInsets ) {
putClientProperty( TABBED_PANE_TAB_INSETS, tabInsets );
}
/**
* Returns the insets of the tab at the given tab index.
*/
public Insets getTabInsets( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
return (Insets) c.getClientProperty( TABBED_PANE_TAB_INSETS );
}
/**
* Specifies the insets of the tab at the given tab index.
*
* @see #setTabHeight(int)
*/
public void setTabInsets( int tabIndex, Insets tabInsets ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_TAB_INSETS, tabInsets );
}
/**
* Returns the insets of the tab area.
*/
public Insets getTabAreaInsets() {
return getClientPropertyInsets( TABBED_PANE_TAB_AREA_INSETS, "TabbedPane.tabAreaInsets" );
}
/**
* Specifies the insets of the tab area.
*/
public void setTabAreaInsets( Insets tabAreaInsets ) {
putClientProperty( TABBED_PANE_TAB_AREA_INSETS, tabAreaInsets );
}
/**
* Returns whether all tabs are closable.
*/
public boolean isTabsClosable() {
return getClientPropertyBoolean( TABBED_PANE_TAB_CLOSABLE, false );
}
/**
* Specifies whether all tabs are closable.
* If set to {@code true}, all tabs in that tabbed pane are closable.
* To make individual tabs closable, use {@link #setTabClosable(int, boolean)}.
*
* Note that you have to specify a callback (see {@link #setTabCloseCallback(BiConsumer)})
* that is invoked when the user clicks a tab close button.
* The callback is responsible for closing the tab.
*/
public void setTabsClosable( boolean tabClosable ) {
putClientPropertyBoolean( TABBED_PANE_TAB_CLOSABLE, tabClosable, false );
}
/**
* Returns whether the tab at the given tab index is closable.
*/
public Boolean isTabClosable( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
Object value = c.getClientProperty( TABBED_PANE_TAB_CLOSABLE );
return (value instanceof Boolean) ? (boolean) value : isTabsClosable();
}
/**
* Specifies whether the tab at the given tab index is closable.
* To make all tabs closable, use {@link #setTabsClosable(boolean)}.
*
* Note that you have to specify a callback (see {@link #setTabCloseCallback(BiConsumer)})
* that is invoked when the user clicks a tab close button.
* The callback is responsible for closing the tab.
*/
public void setTabClosable( int tabIndex, boolean tabClosable ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_TAB_CLOSABLE, tabClosable );
}
/**
* Returns the tooltip text used for tab close buttons.
*/
public String getTabCloseToolTipText() {
return (String) getClientProperty( TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT );
}
/**
* Specifies the tooltip text used for tab close buttons.
*/
public void setTabCloseToolTipText( String tabCloseToolTipText ) {
putClientProperty( TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT, tabCloseToolTipText );
}
/**
* Returns the tooltip text used for tab close button at the given tab index.
*/
public String getTabCloseToolTipText( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
return (String) c.getClientProperty( TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT );
}
/**
* Specifies the tooltip text used for tab close button at the given tab index.
*/
public void setTabCloseToolTipText( int tabIndex, String tabCloseToolTipText ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT, tabCloseToolTipText );
}
/**
* Returns the callback that is invoked when a tab close button is clicked.
* The callback is responsible for closing the tab.
*/
@SuppressWarnings( "unchecked" )
public BiConsumer getTabCloseCallback() {
return (BiConsumer) getClientProperty( TABBED_PANE_TAB_CLOSE_CALLBACK );
}
/**
* Specifies the callback that is invoked when a tab close button is clicked.
* The callback is responsible for closing the tab.
*
* Use a {@link java.util.function.BiConsumer}<javax.swing.JTabbedPane, Integer>
* that receives the tabbed pane and the tab index as parameters:
*
{@code
* myTabbedPane.setTabCloseCallback( (tabbedPane, tabIndex) -> {
* // close tab here
* } );
* }
* If you need to check whether a modifier key (e.g. Alt or Shift) was pressed
* while the user clicked the tab close button, use {@link java.awt.EventQueue#getCurrentEvent}
* to get current event, check whether it is a {@link java.awt.event.MouseEvent}
* and invoke its methods. E.g.
* {@code
* AWTEvent e = EventQueue.getCurrentEvent();
* boolean shift = (e instanceof MouseEvent) ? ((MouseEvent)e).isShiftDown() : false;
* }
*/
public void setTabCloseCallback( BiConsumer tabCloseCallback ) {
putClientProperty( TABBED_PANE_TAB_CLOSE_CALLBACK, tabCloseCallback );
}
/**
* Returns the callback that is invoked when the tab close button at the given tab index is clicked.
* The callback is responsible for closing the tab.
*/
@SuppressWarnings( "unchecked" )
public BiConsumer getTabCloseCallback( int tabIndex ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
return (BiConsumer) c.getClientProperty( TABBED_PANE_TAB_CLOSE_CALLBACK );
}
/**
* Specifies the callback that is invoked when the tab close button at the given tab index is clicked.
* The callback is responsible for closing the tab.
*
* @see #setTabCloseCallback(BiConsumer)
*/
public void setTabCloseCallback( int tabIndex, BiConsumer tabCloseCallback ) {
JComponent c = (JComponent) getComponentAt( tabIndex );
c.putClientProperty( TABBED_PANE_TAB_CLOSE_CALLBACK, tabCloseCallback );
}
// NOTE: enum names must be equal to allowed strings
public enum TabsPopupPolicy { never, asNeeded };
/**
* Returns the display policy for the "more tabs" button,
* which shows a popup menu with the (partly) hidden tabs.
*/
public TabsPopupPolicy getTabsPopupPolicy() {
return getClientPropertyEnumString( TABBED_PANE_TABS_POPUP_POLICY, TabsPopupPolicy.class,
"TabbedPane.tabsPopupPolicy", TabsPopupPolicy.asNeeded );
}
/**
* Specifies the display policy for the "more tabs" button,
* which shows a popup menu with the (partly) hidden tabs.
*/
public void setTabsPopupPolicy( TabsPopupPolicy tabsPopupPolicy ) {
putClientPropertyEnumString( TABBED_PANE_TABS_POPUP_POLICY, tabsPopupPolicy );
}
// NOTE: enum names must be equal to allowed strings
public enum ScrollButtonsPolicy { never, asNeeded, asNeededSingle };
/**
* Returns the display policy for the forward/backward scroll arrow buttons.
*/
public ScrollButtonsPolicy getScrollButtonsPolicy() {
return getClientPropertyEnumString( TABBED_PANE_SCROLL_BUTTONS_POLICY, ScrollButtonsPolicy.class,
"TabbedPane.scrollButtonsPolicy", ScrollButtonsPolicy.asNeededSingle );
}
/**
* Specifies the display policy for the forward/backward scroll arrow buttons.
*/
public void setScrollButtonsPolicy( ScrollButtonsPolicy scrollButtonsPolicy ) {
putClientPropertyEnumString( TABBED_PANE_SCROLL_BUTTONS_POLICY, scrollButtonsPolicy );
}
// NOTE: enum names must be equal to allowed strings
public enum ScrollButtonsPlacement { both, trailing };
/**
* Returns the placement of the forward/backward scroll arrow buttons.
*/
public ScrollButtonsPlacement getScrollButtonsPlacement() {
return getClientPropertyEnumString( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT, ScrollButtonsPlacement.class,
"TabbedPane.scrollButtonsPlacement", ScrollButtonsPlacement.both );
}
/**
* Specifies the placement of the forward/backward scroll arrow buttons.
*/
public void setScrollButtonsPlacement( ScrollButtonsPlacement scrollButtonsPlacement ) {
putClientPropertyEnumString( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT, scrollButtonsPlacement );
}
// NOTE: enum names must be equal to allowed strings
public enum TabAreaAlignment { leading, trailing, center, fill };
/**
* Returns the alignment of the tab area.
*/
public TabAreaAlignment getTabAreaAlignment() {
return getClientPropertyEnumString( TABBED_PANE_TAB_AREA_ALIGNMENT, TabAreaAlignment.class,
"TabbedPane.tabAreaAlignment", TabAreaAlignment.leading );
}
/**
* Specifies the alignment of the tab area.
*/
public void setTabAreaAlignment( TabAreaAlignment tabAreaAlignment ) {
putClientPropertyEnumString( TABBED_PANE_TAB_AREA_ALIGNMENT, tabAreaAlignment );
}
// NOTE: enum names must be equal to allowed strings
public enum TabAlignment { leading, trailing, center };
/**
* Returns the horizontal alignment of the tab title and icon.
*/
public TabAlignment getTabAlignment() {
return getClientPropertyEnumString( TABBED_PANE_TAB_ALIGNMENT, TabAlignment.class,
"TabbedPane.tabAlignment", TabAlignment.center );
}
/**
* Specifies the horizontal alignment of the tab title and icon.
*/
public void setTabAlignment( TabAlignment tabAlignment ) {
putClientPropertyEnumString( TABBED_PANE_TAB_ALIGNMENT, tabAlignment );
}
// NOTE: enum names must be equal to allowed strings
public enum TabWidthMode { preferred, equal, compact };
/**
* Returns how the tabs should be sized.
*/
public TabWidthMode getTabWidthMode() {
return getClientPropertyEnumString( TABBED_PANE_TAB_WIDTH_MODE, TabWidthMode.class,
"TabbedPane.tabWidthMode", TabWidthMode.preferred );
}
/**
* Specifies how the tabs should be sized.
*/
public void setTabWidthMode( TabWidthMode tabWidthMode ) {
putClientPropertyEnumString( TABBED_PANE_TAB_WIDTH_MODE, tabWidthMode );
}
/**
* Returns the tab icon placement (relative to tab title).
*/
public int getTabIconPlacement() {
return getClientPropertyInt( TABBED_PANE_TAB_ICON_PLACEMENT, SwingConstants.LEADING );
}
/**
* Specifies the tab icon placement (relative to tab title).
*
* Allowed Values are:
*
* - {@link SwingConstants#LEADING} (default)
*
- {@link SwingConstants#TRAILING}
*
- {@link SwingConstants#TOP}
*
- {@link SwingConstants#BOTTOM}
*
*/
public void setTabIconPlacement( int tabIconPlacement ) {
putClientProperty( TABBED_PANE_TAB_ICON_PLACEMENT, (tabIconPlacement >= 0) ? tabIconPlacement : null );
}
/**
* Returns a component that will be placed at the leading edge of the tabs area.
*/
public Component getLeadingComponent() {
return (Component) getClientProperty( TABBED_PANE_LEADING_COMPONENT );
}
/**
* Specifies a component that will be placed at the leading edge of the tabs area.
*
* For top and bottom tab placement, the layed out component size will be
* the preferred component width and the tab area height.
* For left and right tab placement, the layed out component size will be
* the tab area width and the preferred component height.
*/
public void setLeadingComponent( Component leadingComponent ) {
putClientProperty( TABBED_PANE_LEADING_COMPONENT, leadingComponent );
}
/**
* Returns a component that will be placed at the trailing edge of the tabs area.
*/
public Component getTrailingComponent() {
return (Component) getClientProperty( TABBED_PANE_TRAILING_COMPONENT );
}
/**
* Specifies a component that will be placed at the trailing edge of the tabs area.
*
* For top and bottom tab placement, the layed out component size will be
* the available horizontal space (minimum is preferred component width) and the tab area height.
* For left and right tab placement, the layed out component size will be
* the tab area width and the available vertical space (minimum is preferred component height).
*/
public void setTrailingComponent( Component trailingComponent ) {
putClientProperty( TABBED_PANE_TRAILING_COMPONENT, trailingComponent );
}
}