diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index b29b573f..fe649536 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -366,28 +366,85 @@ public interface FlatClientProperties String TABBED_PANE_TAB_CLOSE_CALLBACK = "JTabbedPane.tabCloseCallback"; /** - * Specifies how to navigate to hidden tabs. + * Specifies the display policy for the "more tabs" button, + * which shows a popup menu with the (partly) hidden tabs. *
* Component {@link javax.swing.JTabbedPane}
* Value type {@link java.lang.String}
- * Allowed Values {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON}
- * or {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS}
+ * Allowed Values
+ * {@link #TABBED_PANE_POLICY_NEVER} or
+ * {@link #TABBED_PANE_POLICY_AS_NEEDED}
*/
- String TABBED_PANE_HIDDEN_TABS_NAVIGATION = "JTabbedPane.hiddenTabsNavigation";
+ String TABBED_PANE_TABS_POPUP_POLICY = "JTabbedPane.tabsPopupPolicy";
/**
- * Use "more tabs" button for navigation to hidden tabs.
- *
- * @see #TABBED_PANE_HIDDEN_TABS_NAVIGATION
+ * Specifies the display policy for the forward/backward scroll arrow buttons.
+ *
+ * Component {@link javax.swing.JTabbedPane}
+ * Value type {@link java.lang.String}
+ * Allowed Values
+ * {@link #TABBED_PANE_POLICY_NEVER},
+ * {@link #TABBED_PANE_POLICY_AS_NEEDED} or
+ * {@link #TABBED_PANE_POLICY_AS_NEEDED_SINGLE}
*/
- String TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON = "moreTabsButton";
+ String TABBED_PANE_SCROLL_BUTTONS_POLICY = "JTabbedPane.scrollButtondPolicy";
/**
- * Use forward/backward buttons for navigation to hidden tabs.
+ * Display never.
*
- * @see #TABBED_PANE_HIDDEN_TABS_NAVIGATION
+ * @see #TABBED_PANE_TABS_POPUP_POLICY
+ * @see #TABBED_PANE_SCROLL_BUTTONS_POLICY
*/
- String TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS = "arrowButtons";
+ String TABBED_PANE_POLICY_NEVER = "never";
+
+ /**
+ * Display only when needed.
+ *
+ * If used for {@link #TABBED_PANE_SCROLL_BUTTONS_POLICY}, both scroll arrow buttons + * are either shown or hidden. Buttons are disabled if scrolling in that + * direction is not applicable. + * + * @see #TABBED_PANE_TABS_POPUP_POLICY + * @see #TABBED_PANE_SCROLL_BUTTONS_POLICY + */ + String TABBED_PANE_POLICY_AS_NEEDED = "asNeeded"; + + /** + * Display single button only when needed. + *
+ * If scroll button placement is trailing, then this option is ignored + * and both buttons are shown or hidden as needed. + * + * @see #TABBED_PANE_SCROLL_BUTTONS_POLICY + */ + String TABBED_PANE_POLICY_AS_NEEDED_SINGLE = "asNeededSingle"; + + /** + * Specifies the placement of the forward/backward scroll arrow buttons. + *
+ * Component {@link javax.swing.JTabbedPane}
+ * Value type {@link java.lang.String}
+ * Allowed Values
+ * {@link #TABBED_PANE_PLACEMENT_BOTH} or
+ * {@link #TABBED_PANE_PLACEMENT_TRAILING}
+ */
+ String TABBED_PANE_SCROLL_BUTTONS_PLACEMENT = "JTabbedPane.scrollButtonsPlacement";
+
+ /**
+ * The forward/backward scroll arrow buttons are placed on both sides of the tab area.
+ * The backward scroll button at the left/top side.
+ * The forward scroll button at the right/bottom side.
+ *
+ * @see #TABBED_PANE_SCROLL_BUTTONS_PLACEMENT
+ */
+ String TABBED_PANE_PLACEMENT_BOTH = "both";
+
+ /**
+ * The forward/backward scroll arrow buttons are placed on the trailing side of the tab area.
+ *
+ * @see #TABBED_PANE_SCROLL_BUTTONS_PLACEMENT
+ */
+ String TABBED_PANE_PLACEMENT_TRAILING = "trailing";
/**
* Specifies the alignment of the tab area.
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
index ed301e1b..27f6546d 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java
@@ -130,7 +130,11 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.showTabSeparators boolean
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
* @uiDefault TabbedPane.hasFullBorder boolean
- * @uiDefault TabbedPane.hiddenTabsNavigation String moreTabsButton (default) or arrowButtons
+ *
+ * @uiDefault TabbedPane.tabsPopupPolicy String never or asNeeded (default)
+ * @uiDefault TabbedPane.scrollButtonsPolicy String never, asNeeded or asNeededSingle (default)
+ * @uiDefault TabbedPane.scrollButtonsPlacement String both (default) or trailing
+ *
* @uiDefault TabbedPane.tabAreaAlignment String leading (default), center, trailing or fill
* @uiDefault TabbedPane.tabAlignment String leading, center (default) or trailing
* @uiDefault TabbedPane.tabWidthMode String preferred (default), equal or compact
@@ -150,9 +154,14 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatTabbedPaneUI
extends BasicTabbedPaneUI
{
- // hidden tabs navigation types
- protected static final int MORE_TABS_BUTTON = 0;
- protected static final int ARROW_BUTTONS = 1;
+ // tabs popup policy / scroll arrows policy
+ protected static final int NEVER = 0;
+// protected static final int ALWAYS = 1;
+ protected static final int AS_NEEDED = 2;
+ protected static final int AS_NEEDED_SINGLE = 3;
+
+ // scroll arrows placement
+ protected static final int BOTH = 100;
// tab area alignment
protected static final int FILL = 100;
@@ -186,10 +195,13 @@ public class FlatTabbedPaneUI
protected boolean hasFullBorder;
protected boolean tabsOpaque = true;
- private String hiddenTabsNavigationStr;
- protected int tabAreaAlignment;
- protected int tabAlignment;
- private String tabWidthModeStr;
+ private int tabsPopupPolicy;
+ private int scrollButtonsPolicy;
+ private int scrollButtonsPlacement;
+
+ private int tabAreaAlignment;
+ private int tabAlignment;
+ private int tabWidthMode;
protected Icon closeIcon;
protected String arrowType;
@@ -273,10 +285,14 @@ public class FlatTabbedPaneUI
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
- hiddenTabsNavigationStr = UIManager.getString( "TabbedPane.hiddenTabsNavigation" );
+
+ tabsPopupPolicy = parseTabsPopupPolicy( UIManager.getString( "TabbedPane.tabsPopupPolicy" ) );
+ scrollButtonsPolicy = parseScrollButtonsPolicy( UIManager.getString( "TabbedPane.scrollButtonsPolicy" ) );
+ scrollButtonsPlacement = parseScrollButtonsPlacement( UIManager.getString( "TabbedPane.scrollButtonsPlacement" ) );
+
tabAreaAlignment = parseAlignment( UIManager.getString( "TabbedPane.tabAreaAlignment" ), LEADING );
tabAlignment = parseAlignment( UIManager.getString( "TabbedPane.tabAlignment" ), CENTER );
- tabWidthModeStr = UIManager.getString( "TabbedPane.tabWidthMode" );
+ tabWidthMode = parseTabWidthMode( UIManager.getString( "TabbedPane.tabWidthMode" ) );
closeIcon = UIManager.getIcon( "TabbedPane.closeIcon" );
buttonInsets = UIManager.getInsets( "TabbedPane.buttonInsets" );
@@ -1197,11 +1213,28 @@ public class FlatTabbedPaneUI
return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
}
- protected int getHiddenTabsNavigation() {
- String str = (String) tabPane.getClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION );
- if( str == null )
- str = hiddenTabsNavigationStr;
- return parseHiddenTabsNavigation( str );
+ protected int getTabsPopupPolicy() {
+ Object value = tabPane.getClientProperty( TABBED_PANE_TABS_POPUP_POLICY );
+
+ return (value instanceof String)
+ ? parseTabsPopupPolicy( (String) value )
+ : tabsPopupPolicy;
+ }
+
+ protected int getScrollButtonsPolicy() {
+ Object value = tabPane.getClientProperty( TABBED_PANE_SCROLL_BUTTONS_POLICY );
+
+ return (value instanceof String)
+ ? parseScrollButtonsPolicy( (String) value )
+ : scrollButtonsPolicy;
+ }
+
+ protected int getScrollButtonsPlacement() {
+ Object value = tabPane.getClientProperty( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT );
+
+ return (value instanceof String)
+ ? parseScrollButtonsPlacement( (String) value )
+ : scrollButtonsPlacement;
}
protected int getTabAreaAlignment() {
@@ -1225,20 +1258,44 @@ public class FlatTabbedPaneUI
}
protected int getTabWidthMode() {
- String str = (String) tabPane.getClientProperty( TABBED_PANE_TAB_WIDTH_MODE );
- if( str == null )
- str = tabWidthModeStr;
- return parseTabWidthMode( str );
+ Object value = tabPane.getClientProperty( TABBED_PANE_TAB_WIDTH_MODE );
+
+ return (value instanceof String)
+ ? parseTabWidthMode( (String) value )
+ : tabWidthMode;
}
- protected static int parseHiddenTabsNavigation( String str ) {
+ protected static int parseTabsPopupPolicy( String str ) {
if( str == null )
- return MORE_TABS_BUTTON;
+ return AS_NEEDED;
switch( str ) {
default:
- case TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON: return MORE_TABS_BUTTON;
- case TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS: return ARROW_BUTTONS;
+ case TABBED_PANE_POLICY_AS_NEEDED: return AS_NEEDED;
+ case TABBED_PANE_POLICY_NEVER: return NEVER;
+ }
+ }
+
+ protected static int parseScrollButtonsPolicy( String str ) {
+ if( str == null )
+ return AS_NEEDED_SINGLE;
+
+ switch( str ) {
+ default:
+ case TABBED_PANE_POLICY_AS_NEEDED_SINGLE: return AS_NEEDED_SINGLE;
+ case TABBED_PANE_POLICY_AS_NEEDED: return AS_NEEDED;
+ case TABBED_PANE_POLICY_NEVER: return NEVER;
+ }
+ }
+
+ protected static int parseScrollButtonsPlacement( String str ) {
+ if( str == null )
+ return BOTH;
+
+ switch( str ) {
+ default:
+ case TABBED_PANE_PLACEMENT_BOTH: return BOTH;
+ case TABBED_PANE_PLACEMENT_TRAILING: return TRAILING;
}
}
@@ -1419,6 +1476,7 @@ public class FlatTabbedPaneUI
super( direction, arrowType,
FlatTabbedPaneUI.this.foreground, FlatTabbedPaneUI.this.disabledForeground,
null, buttonHoverBackground, null, buttonPressedBackground );
+ setArrowWidth( 10 );
}
@Override
@@ -2127,7 +2185,11 @@ public class FlatTabbedPaneUI
case TABBED_PANE_TAB_HEIGHT:
case TABBED_PANE_TAB_INSETS:
case TABBED_PANE_TAB_AREA_INSETS:
- case TABBED_PANE_HIDDEN_TABS_NAVIGATION:
+
+ case TABBED_PANE_TABS_POPUP_POLICY:
+ case TABBED_PANE_SCROLL_BUTTONS_POLICY:
+ case TABBED_PANE_SCROLL_BUTTONS_PLACEMENT:
+
case TABBED_PANE_TAB_AREA_ALIGNMENT:
case TABBED_PANE_TAB_ALIGNMENT:
case TABBED_PANE_TAB_WIDTH_MODE:
@@ -2488,14 +2550,23 @@ public class FlatTabbedPaneUI
delegate.layoutContainer( parent );
} );
- boolean useMoreButton = (getHiddenTabsNavigation() == MORE_TABS_BUTTON);
+ int tabsPopupPolicy = getTabsPopupPolicy();
+ int scrollButtonsPolicy = getScrollButtonsPolicy();
+ int scrollButtonsPlacement = getScrollButtonsPlacement();
+
+ boolean useMoreTabsButton = (tabsPopupPolicy == AS_NEEDED);
+ boolean useScrollButtons = (scrollButtonsPolicy == AS_NEEDED || scrollButtonsPolicy == AS_NEEDED_SINGLE);
+ boolean hideDisabledScrollButtons = (scrollButtonsPolicy == AS_NEEDED_SINGLE && scrollButtonsPlacement == BOTH);
+ boolean trailingScrollButtons = (scrollButtonsPlacement == TRAILING);
// for right-to-left always use "more tabs" button for horizontal scrolling
// because methods scrollForward() and scrollBackward() in class
// BasicTabbedPaneUI.ScrollableTabSupport do not work for right-to-left
boolean leftToRight = isLeftToRight();
- if( !leftToRight && !useMoreButton && isHorizontalTabPlacement() )
- useMoreButton = true;
+ if( !leftToRight && !useMoreTabsButton && isHorizontalTabPlacement() ) {
+ useMoreTabsButton = true;
+ useScrollButtons = false;
+ }
// find backward/forward scroll buttons
JButton backwardButton = null;
@@ -2510,7 +2581,7 @@ public class FlatTabbedPaneUI
}
}
- if( !useMoreButton && (backwardButton == null || forwardButton == null) )
+ if( !useMoreTabsButton && (backwardButton == null || forwardButton == null) )
return; // should never occur
Rectangle bounds = tabPane.getBounds();
@@ -2518,10 +2589,9 @@ public class FlatTabbedPaneUI
int tabPlacement = tabPane.getTabPlacement();
int tabAreaAlignment = getTabAreaAlignment();
Insets tabAreaInsets = getRealTabAreaInsets( tabPlacement );
- Dimension moreButtonSize = useMoreButton ? moreTabsButton.getPreferredSize() : null;
- Dimension backwardButtonSize = useMoreButton ? null : backwardButton.getPreferredSize();
- Dimension forwardButtonSize = useMoreButton ? null : forwardButton.getPreferredSize();
- boolean buttonsVisible = false;
+ boolean moreTabsButtonVisible = false;
+ boolean backwardButtonVisible = false;
+ boolean forwardButtonVisible = false;
// TabbedPaneScrollLayout adds tabAreaInsets to tab coordinates,
// but we use it to position the viewport
@@ -2603,22 +2673,49 @@ public class FlatTabbedPaneUI
int twi = tw - leftWidth - rightWidth - tabAreaInsets.left - tabAreaInsets.right;
// layout viewport and buttons
- int viewportWidth = twi;
- if( viewportWidth < totalTabWidth ) {
- // need buttons
- buttonsVisible = true;
- int buttonsWidth = useMoreButton ? moreButtonSize.width : (backwardButtonSize.width + forwardButtonSize.width);
- viewportWidth = Math.max( viewportWidth - buttonsWidth, 0 );
+ int x = txi;
+ int w = twi;
- if( useMoreButton )
- moreTabsButton.setBounds( leftToRight ? (txi + twi - buttonsWidth) : txi, ty, moreButtonSize.width, th );
- else {
- backwardButton.setBounds( leftToRight ? (txi + twi - buttonsWidth) : txi, ty, backwardButtonSize.width, th );
- forwardButton.setBounds( leftToRight ? (txi + twi - forwardButtonSize.width) : (txi + backwardButtonSize.width), ty, forwardButtonSize.width, th );
+ if( w < totalTabWidth ) {
+ // available width is too small for all tabs --> need buttons
+
+ // layout more button on trailing side
+ if( useMoreTabsButton ) {
+ int buttonWidth = moreTabsButton.getPreferredSize().width;
+ moreTabsButton.setBounds( leftToRight ? (x + w - buttonWidth) : x, ty, buttonWidth, th );
+ x += leftToRight ? 0 : buttonWidth;
+ w -= buttonWidth;
+ moreTabsButtonVisible = true;
}
- tabViewport.setBounds( leftToRight ? txi : (txi + buttonsWidth), ty, viewportWidth, th );
- } else
- tabViewport.setBounds( txi, ty, viewportWidth, th );
+ if( useScrollButtons ) {
+ // layout forward button on trailing side
+ if( !hideDisabledScrollButtons || forwardButton.isEnabled() ) {
+ int buttonWidth = forwardButton.getPreferredSize().width;
+ forwardButton.setBounds( leftToRight ? (x + w - buttonWidth) : x, ty, buttonWidth, th );
+ x += leftToRight ? 0 : buttonWidth;
+ w -= buttonWidth;
+ forwardButtonVisible = true;
+ }
+
+ // layout backward button
+ if( !hideDisabledScrollButtons || backwardButton.isEnabled() ) {
+ int buttonWidth = backwardButton.getPreferredSize().width;
+ if( trailingScrollButtons ) {
+ // on trailing side
+ backwardButton.setBounds( leftToRight ? (x + w - buttonWidth) : x, ty, buttonWidth, th );
+ x += leftToRight ? 0 : buttonWidth;
+ } else {
+ // on leading side
+ backwardButton.setBounds( leftToRight ? x : (x + w - buttonWidth), ty, buttonWidth, th );
+ x += leftToRight ? buttonWidth : 0;
+ }
+ w -= buttonWidth;
+ backwardButtonVisible = true;
+ }
+ }
+ }
+
+ tabViewport.setBounds( x, ty, w, th );
if( !leftToRight ) {
// layout viewport so that we can get correct view width below
@@ -2686,29 +2783,54 @@ public class FlatTabbedPaneUI
int thi = th - topHeight - bottomHeight - tabAreaInsets.top - tabAreaInsets.bottom;
// layout viewport and buttons
- int viewportHeight = thi;
- if( viewportHeight < totalTabHeight ) {
- // need buttons
- buttonsVisible = true;
- int buttonsHeight = useMoreButton ? moreButtonSize.height : (backwardButtonSize.height + forwardButtonSize.height);
- viewportHeight = Math.max( viewportHeight - buttonsHeight, 0 );
+ int y = tyi;
+ int h = thi;
- if( useMoreButton )
- moreTabsButton.setBounds( tx, tyi + thi - buttonsHeight, tw, moreButtonSize.height );
- else {
- backwardButton.setBounds( tx, tyi + thi - buttonsHeight, tw, backwardButtonSize.height );
- forwardButton.setBounds( tx, tyi + thi - forwardButtonSize.height, tw, forwardButtonSize.height );
+ if( h < totalTabHeight ) {
+ // available height is too small for all tabs --> need buttons
+
+ // layout more button on bottom side
+ if( useMoreTabsButton ) {
+ int buttonHeight = moreTabsButton.getPreferredSize().height;
+ moreTabsButton.setBounds( tx, y + h - buttonHeight, tw, buttonHeight );
+ h -= buttonHeight;
+ moreTabsButtonVisible = true;
+ }
+ if( useScrollButtons ) {
+ // layout forward button on bottom side
+ if( !hideDisabledScrollButtons || forwardButton.isEnabled() ) {
+ int buttonHeight = forwardButton.getPreferredSize().height;
+ forwardButton.setBounds( tx, y + h - buttonHeight, tw, buttonHeight );
+ h -= buttonHeight;
+ forwardButtonVisible = true;
+ }
+
+ // layout backward button
+ if( !hideDisabledScrollButtons || backwardButton.isEnabled() ) {
+ int buttonHeight = backwardButton.getPreferredSize().height;
+ if( trailingScrollButtons ) {
+ // on bottom side
+ backwardButton.setBounds( tx, y + h - buttonHeight, tw, buttonHeight );
+ } else {
+ // on top side
+ backwardButton.setBounds( tx, y, tw, buttonHeight );
+ y += buttonHeight;
+ }
+ h -= buttonHeight;
+ backwardButtonVisible = true;
+ }
}
}
- tabViewport.setBounds( tx, tyi, tw, viewportHeight );
+
+ tabViewport.setBounds( tx, y, tw, h );
}
}
// show/hide viewport and buttons
tabViewport.setVisible( rects.length > 0 );
- moreTabsButton.setVisible( useMoreButton && buttonsVisible );
- backwardButton.setVisible( !useMoreButton && buttonsVisible );
- forwardButton.setVisible( !useMoreButton && buttonsVisible );
+ moreTabsButton.setVisible( moreTabsButtonVisible );
+ backwardButton.setVisible( backwardButtonVisible );
+ forwardButton.setVisible( forwardButtonVisible );
}
}
}
diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
index 22b086a8..42786726 100644
--- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
+++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
@@ -573,6 +573,13 @@ TabbedPane.arrowType=chevron
TabbedPane.buttonInsets=2,1,2,1
TabbedPane.buttonArc=$Button.arc
+# allowed values: never or asNeeded
+TabbedPane.tabsPopupPolicy=asNeeded
+# allowed values: never, asNeeded or asNeededSingle
+TabbedPane.scrollButtonsPolicy=asNeededSingle
+# allowed values: both or trailing
+TabbedPane.scrollButtonsPlacement=both
+
TabbedPane.closeIcon=com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon
TabbedPane.closeSize=16,16
TabbedPane.closeArc=4
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java
index dd98255c..d950fedf 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java
@@ -137,7 +137,6 @@ public class FlatContainerTest
tabbedPane.addTab( "Tab " + index, createTab( "tab content " + index ) );
break;
}
-
}
private JComponent createTab( String text ) {
@@ -262,11 +261,25 @@ public class FlatContainerTest
tabbedPane4.setTabPlacement( (tabPlacement >= 0) ? tabPlacement : SwingConstants.RIGHT );
}
- private void hiddenTabsNavigationChanged() {
- String value = (String) hiddenTabsNavigationField.getSelectedItem();
+ private void tabsPopupPolicyChanged() {
+ String value = (String) tabsPopupPolicyField.getSelectedItem();
if( "default".equals( value ) )
value = null;
- putTabbedPanesClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value );
+ putTabbedPanesClientProperty( TABBED_PANE_TABS_POPUP_POLICY, value );
+ }
+
+ private void scrollButtonsPolicyChanged() {
+ String value = (String) scrollButtonsPolicyField.getSelectedItem();
+ if( "default".equals( value ) )
+ value = null;
+ putTabbedPanesClientProperty( TABBED_PANE_SCROLL_BUTTONS_POLICY, value );
+ }
+
+ private void scrollButtonsPlacementChanged() {
+ String value = (String) scrollButtonsPlacementField.getSelectedItem();
+ if( "default".equals( value ) )
+ value = null;
+ putTabbedPanesClientProperty( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT, value );
}
private void tabAreaAlignmentChanged() {
@@ -417,33 +430,37 @@ public class FlatContainerTest
customTabsCheckBox = new JCheckBox();
htmlTabsCheckBox = new JCheckBox();
multiLineTabsCheckBox = new JCheckBox();
- JLabel hiddenTabsNavigationLabel = new JLabel();
- hiddenTabsNavigationField = new JComboBox<>();
+ JLabel tabsPopupPolicyLabel = new JLabel();
+ tabsPopupPolicyField = new JComboBox<>();
tabBackForegroundCheckBox = new JCheckBox();
- JLabel tabPlacementLabel = new JLabel();
- tabPlacementField = new JComboBox<>();
+ JLabel scrollButtonsPolicyLabel = new JLabel();
+ scrollButtonsPolicyField = new JComboBox<>();
tabIconsCheckBox = new JCheckBox();
tabIconSizeSpinner = new JSpinner();
iconPlacementField = new JComboBox<>();
+ JLabel scrollButtonsPlacementLabel = new JLabel();
+ scrollButtonsPlacementField = new JComboBox<>();
+ tabsClosableCheckBox = new JCheckBox();
+ JLabel tabPlacementLabel = new JLabel();
+ tabPlacementField = new JComboBox<>();
+ secondTabClosableCheckBox = new TriStateCheckBox();
JLabel tabAreaAlignmentLabel = new JLabel();
tabAreaAlignmentField = new JComboBox<>();
tabAlignmentField = new JComboBox<>();
JLabel tabWidthModeLabel = new JLabel();
tabWidthModeField = new JComboBox<>();
- tabsClosableCheckBox = new JCheckBox();
+ leadingComponentCheckBox = new JCheckBox();
customBorderCheckBox = new JCheckBox();
tabAreaInsetsCheckBox = new JCheckBox();
- secondTabClosableCheckBox = new TriStateCheckBox();
+ trailingComponentCheckBox = new JCheckBox();
hasFullBorderCheckBox = new JCheckBox();
smallerTabHeightCheckBox = new JCheckBox();
- leadingComponentCheckBox = new JCheckBox();
+ minimumTabWidthCheckBox = new JCheckBox();
hideContentSeparatorCheckBox = new JCheckBox();
smallerInsetsCheckBox = new JCheckBox();
- trailingComponentCheckBox = new JCheckBox();
+ maximumTabWidthCheckBox = new JCheckBox();
showTabSeparatorsCheckBox = new JCheckBox();
secondTabWiderCheckBox = new JCheckBox();
- minimumTabWidthCheckBox = new JCheckBox();
- maximumTabWidthCheckBox = new JCheckBox();
CellConstraints cc = new CellConstraints();
//======== this ========
@@ -556,7 +573,7 @@ public class FlatContainerTest
"[center]" +
"[]" +
"[]" +
- "[]para" +
+ "[]" +
"[]" +
"[]para" +
"[]" +
@@ -594,38 +611,37 @@ public class FlatContainerTest
multiLineTabsCheckBox.addActionListener(e -> htmlTabsChanged());
tabbedPaneControlPanel.add(multiLineTabsCheckBox, "cell 2 0");
- //---- hiddenTabsNavigationLabel ----
- hiddenTabsNavigationLabel.setText("Hidden tabs navigation:");
- tabbedPaneControlPanel.add(hiddenTabsNavigationLabel, "cell 0 1");
+ //---- tabsPopupPolicyLabel ----
+ tabsPopupPolicyLabel.setText("Tabs popup policy:");
+ tabbedPaneControlPanel.add(tabsPopupPolicyLabel, "cell 0 1");
- //---- hiddenTabsNavigationField ----
- hiddenTabsNavigationField.setModel(new DefaultComboBoxModel<>(new String[] {
+ //---- tabsPopupPolicyField ----
+ tabsPopupPolicyField.setModel(new DefaultComboBoxModel<>(new String[] {
"default",
- "moreTabsButton",
- "arrowButtons"
+ "asNeeded",
+ "never"
}));
- hiddenTabsNavigationField.addActionListener(e -> hiddenTabsNavigationChanged());
- tabbedPaneControlPanel.add(hiddenTabsNavigationField, "cell 1 1");
+ tabsPopupPolicyField.addActionListener(e -> tabsPopupPolicyChanged());
+ tabbedPaneControlPanel.add(tabsPopupPolicyField, "cell 1 1");
//---- tabBackForegroundCheckBox ----
tabBackForegroundCheckBox.setText("Tab back/foreground");
tabBackForegroundCheckBox.addActionListener(e -> tabBackForegroundChanged());
tabbedPaneControlPanel.add(tabBackForegroundCheckBox, "cell 2 1");
- //---- tabPlacementLabel ----
- tabPlacementLabel.setText("Tab placement:");
- tabbedPaneControlPanel.add(tabPlacementLabel, "cell 0 2");
+ //---- scrollButtonsPolicyLabel ----
+ scrollButtonsPolicyLabel.setText("Scroll buttons policy:");
+ tabbedPaneControlPanel.add(scrollButtonsPolicyLabel, "cell 0 2");
- //---- tabPlacementField ----
- tabPlacementField.setModel(new DefaultComboBoxModel<>(new String[] {
+ //---- scrollButtonsPolicyField ----
+ scrollButtonsPolicyField.setModel(new DefaultComboBoxModel<>(new String[] {
"default",
- "top",
- "bottom",
- "left",
- "right"
+ "asNeededSingle",
+ "asNeeded",
+ "never"
}));
- tabPlacementField.addActionListener(e -> tabPlacementChanged());
- tabbedPaneControlPanel.add(tabPlacementField, "cell 1 2");
+ scrollButtonsPolicyField.addActionListener(e -> scrollButtonsPolicyChanged());
+ tabbedPaneControlPanel.add(scrollButtonsPolicyField, "cell 1 2");
//---- tabIconsCheckBox ----
tabIconsCheckBox.setText("Tab icons");
@@ -648,9 +664,47 @@ public class FlatContainerTest
iconPlacementField.addActionListener(e -> iconPlacementChanged());
tabbedPaneControlPanel.add(iconPlacementField, "cell 2 2");
+ //---- scrollButtonsPlacementLabel ----
+ scrollButtonsPlacementLabel.setText("Scroll buttons placement:");
+ tabbedPaneControlPanel.add(scrollButtonsPlacementLabel, "cell 0 3");
+
+ //---- scrollButtonsPlacementField ----
+ scrollButtonsPlacementField.setModel(new DefaultComboBoxModel<>(new String[] {
+ "default",
+ "both",
+ "trailing"
+ }));
+ scrollButtonsPlacementField.addActionListener(e -> scrollButtonsPlacementChanged());
+ tabbedPaneControlPanel.add(scrollButtonsPlacementField, "cell 1 3");
+
+ //---- tabsClosableCheckBox ----
+ tabsClosableCheckBox.setText("Tabs closable");
+ tabsClosableCheckBox.addActionListener(e -> tabsClosableChanged());
+ tabbedPaneControlPanel.add(tabsClosableCheckBox, "cell 2 3");
+
+ //---- tabPlacementLabel ----
+ tabPlacementLabel.setText("Tab placement:");
+ tabbedPaneControlPanel.add(tabPlacementLabel, "cell 0 4");
+
+ //---- tabPlacementField ----
+ tabPlacementField.setModel(new DefaultComboBoxModel<>(new String[] {
+ "default",
+ "top",
+ "bottom",
+ "left",
+ "right"
+ }));
+ tabPlacementField.addActionListener(e -> tabPlacementChanged());
+ tabbedPaneControlPanel.add(tabPlacementField, "cell 1 4");
+
+ //---- secondTabClosableCheckBox ----
+ secondTabClosableCheckBox.setText("Second Tab closable");
+ secondTabClosableCheckBox.addActionListener(e -> secondTabClosableChanged());
+ tabbedPaneControlPanel.add(secondTabClosableCheckBox, "cell 2 4");
+
//---- tabAreaAlignmentLabel ----
tabAreaAlignmentLabel.setText("Tab area/title alignment:");
- tabbedPaneControlPanel.add(tabAreaAlignmentLabel, "cell 0 3");
+ tabbedPaneControlPanel.add(tabAreaAlignmentLabel, "cell 0 5");
//---- tabAreaAlignmentField ----
tabAreaAlignmentField.setModel(new DefaultComboBoxModel<>(new String[] {
@@ -661,7 +715,7 @@ public class FlatContainerTest
"fill"
}));
tabAreaAlignmentField.addActionListener(e -> tabAreaAlignmentChanged());
- tabbedPaneControlPanel.add(tabAreaAlignmentField, "cell 1 3");
+ tabbedPaneControlPanel.add(tabAreaAlignmentField, "cell 1 5");
//---- tabAlignmentField ----
tabAlignmentField.setModel(new DefaultComboBoxModel<>(new String[] {
@@ -671,11 +725,11 @@ public class FlatContainerTest
"center"
}));
tabAlignmentField.addActionListener(e -> tabAlignmentChanged());
- tabbedPaneControlPanel.add(tabAlignmentField, "cell 1 3");
+ tabbedPaneControlPanel.add(tabAlignmentField, "cell 1 5");
//---- tabWidthModeLabel ----
tabWidthModeLabel.setText("Tab width mode:");
- tabbedPaneControlPanel.add(tabWidthModeLabel, "cell 2 3");
+ tabbedPaneControlPanel.add(tabWidthModeLabel, "cell 2 5");
//---- tabWidthModeField ----
tabWidthModeField.setModel(new DefaultComboBoxModel<>(new String[] {
@@ -685,77 +739,67 @@ public class FlatContainerTest
"compact"
}));
tabWidthModeField.addActionListener(e -> tabWidthModeChanged());
- tabbedPaneControlPanel.add(tabWidthModeField, "cell 2 3");
-
- //---- tabsClosableCheckBox ----
- tabsClosableCheckBox.setText("Tabs closable");
- tabsClosableCheckBox.addActionListener(e -> tabsClosableChanged());
- tabbedPaneControlPanel.add(tabsClosableCheckBox, "cell 0 4");
-
- //---- customBorderCheckBox ----
- customBorderCheckBox.setText("Custom border");
- customBorderCheckBox.addActionListener(e -> customBorderChanged());
- tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 4");
-
- //---- tabAreaInsetsCheckBox ----
- tabAreaInsetsCheckBox.setText("Tab area insets (5,5,10,10)");
- tabAreaInsetsCheckBox.addActionListener(e -> tabAreaInsetsChanged());
- tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 4");
-
- //---- secondTabClosableCheckBox ----
- secondTabClosableCheckBox.setText("Second Tab closable");
- secondTabClosableCheckBox.addActionListener(e -> secondTabClosableChanged());
- tabbedPaneControlPanel.add(secondTabClosableCheckBox, "cell 0 5");
-
- //---- hasFullBorderCheckBox ----
- hasFullBorderCheckBox.setText("Show content border");
- hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
- tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 5,alignx left,growx 0");
-
- //---- smallerTabHeightCheckBox ----
- smallerTabHeightCheckBox.setText("Smaller tab height (26)");
- smallerTabHeightCheckBox.addActionListener(e -> smallerTabHeightChanged());
- tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 5");
+ tabbedPaneControlPanel.add(tabWidthModeField, "cell 2 5");
//---- leadingComponentCheckBox ----
leadingComponentCheckBox.setText("Leading component");
leadingComponentCheckBox.addActionListener(e -> leadingComponentChanged());
tabbedPaneControlPanel.add(leadingComponentCheckBox, "cell 0 6");
- //---- hideContentSeparatorCheckBox ----
- hideContentSeparatorCheckBox.setText("Hide content separator");
- hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
- tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 6");
+ //---- customBorderCheckBox ----
+ customBorderCheckBox.setText("Custom border");
+ customBorderCheckBox.addActionListener(e -> customBorderChanged());
+ tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 6");
- //---- smallerInsetsCheckBox ----
- smallerInsetsCheckBox.setText("Smaller tab insets (2,2,2,2)");
- smallerInsetsCheckBox.addActionListener(e -> smallerInsetsChanged());
- tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 6");
+ //---- tabAreaInsetsCheckBox ----
+ tabAreaInsetsCheckBox.setText("Tab area insets (5,5,10,10)");
+ tabAreaInsetsCheckBox.addActionListener(e -> tabAreaInsetsChanged());
+ tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 6");
//---- trailingComponentCheckBox ----
trailingComponentCheckBox.setText("Trailing component");
trailingComponentCheckBox.addActionListener(e -> trailingComponentChanged());
tabbedPaneControlPanel.add(trailingComponentCheckBox, "cell 0 7");
- //---- showTabSeparatorsCheckBox ----
- showTabSeparatorsCheckBox.setText("Show tab separators");
- showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
- tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 7");
+ //---- hasFullBorderCheckBox ----
+ hasFullBorderCheckBox.setText("Show content border");
+ hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
+ tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 7,alignx left,growx 0");
- //---- secondTabWiderCheckBox ----
- secondTabWiderCheckBox.setText("Second Tab insets wider (4,20,4,20)");
- secondTabWiderCheckBox.addActionListener(e -> secondTabWiderChanged());
- tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 7");
+ //---- smallerTabHeightCheckBox ----
+ smallerTabHeightCheckBox.setText("Smaller tab height (26)");
+ smallerTabHeightCheckBox.addActionListener(e -> smallerTabHeightChanged());
+ tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 7");
//---- minimumTabWidthCheckBox ----
minimumTabWidthCheckBox.setText("Minimum tab width (100)");
minimumTabWidthCheckBox.addActionListener(e -> minimumTabWidthChanged());
- tabbedPaneControlPanel.add(minimumTabWidthCheckBox, "cell 2 8");
+ tabbedPaneControlPanel.add(minimumTabWidthCheckBox, "cell 0 8");
+
+ //---- hideContentSeparatorCheckBox ----
+ hideContentSeparatorCheckBox.setText("Hide content separator");
+ hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
+ tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 8");
+
+ //---- smallerInsetsCheckBox ----
+ smallerInsetsCheckBox.setText("Smaller tab insets (2,2,2,2)");
+ smallerInsetsCheckBox.addActionListener(e -> smallerInsetsChanged());
+ tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 8");
//---- maximumTabWidthCheckBox ----
maximumTabWidthCheckBox.setText("Maximum tab width (60)");
maximumTabWidthCheckBox.addActionListener(e -> maximumTabWidthChanged());
- tabbedPaneControlPanel.add(maximumTabWidthCheckBox, "cell 2 9");
+ tabbedPaneControlPanel.add(maximumTabWidthCheckBox, "cell 0 9");
+
+ //---- showTabSeparatorsCheckBox ----
+ showTabSeparatorsCheckBox.setText("Show tab separators");
+ showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
+ tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 9");
+
+ //---- secondTabWiderCheckBox ----
+ secondTabWiderCheckBox.setText("Second Tab insets wider (4,20,4,20)");
+ secondTabWiderCheckBox.addActionListener(e -> secondTabWiderChanged());
+ tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 9");
}
panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1));
}
@@ -775,29 +819,31 @@ public class FlatContainerTest
private JCheckBox customTabsCheckBox;
private JCheckBox htmlTabsCheckBox;
private JCheckBox multiLineTabsCheckBox;
- private JComboBox