From 08419d613596c3e8a760fe12caec5a8d425b3c9b Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 29 Nov 2025 18:11:31 +0100 Subject: [PATCH] TabbedPane: - added icon-only tab mode, which shows tab icons but hides tab titles - in "Show Hidden Tabs" popup menu, do not show text "x. Tab" if tab has icon but no title (issue #1062) --- CHANGELOG.md | 5 ++ .../formdev/flatlaf/FlatClientProperties.java | 13 +++- .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 25 +++++-- .../com/formdev/flatlaf/FlatLaf.properties | 2 +- .../com/formdev/flatlaf/demo/TabsPanel.java | 67 +++++++++++++++++-- .../com/formdev/flatlaf/demo/TabsPanel.jfd | 37 +++++++--- .../extras/components/FlatTabbedPane.java | 2 +- 7 files changed, 122 insertions(+), 29 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b06c24fa..5d20ae1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,16 @@ FlatLaf Change Log - System File Chooser allows using **operating system file dialogs** in Java Swing applications. (PR #988) - Zooming API. (PR #1051) +- TabbedPane: Added icon-only tab mode, which shows tab icons but hides tab + titles. Tab titles are used in "Show Hidden Tabs" popup menu. (set client + property `JTabbedPane.tabWidthMode` to `"iconOnly"`) #### Fixed bugs - CheckBox and RadioButton: Fixed styling of custom icon. Also fixed focus width (and preferred size) if using custom icon. (PR #1060) +- TabbedPane: In "Show Hidden Tabs" popup menu, do not show text "x. Tab" if tab + has icon but no title. (issue #1062) - TextField: Fixed wrong leading/trailing icon placement if border is set to `null`. (issue #1047) - Extras: UI defaults inspector: Exclude inspector window from being blocked by 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 e26b7ec3..9962d69f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -1086,8 +1086,9 @@ public interface FlatClientProperties * Value type {@link java.lang.String}
* Allowed Values * {@link #TABBED_PANE_TAB_WIDTH_MODE_PREFERRED} (default), - * {@link #TABBED_PANE_TAB_WIDTH_MODE_EQUAL} or - * {@link #TABBED_PANE_TAB_WIDTH_MODE_COMPACT} + * {@link #TABBED_PANE_TAB_WIDTH_MODE_EQUAL}, + * {@link #TABBED_PANE_TAB_WIDTH_MODE_COMPACT} or + * {@link #TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY} */ String TABBED_PANE_TAB_WIDTH_MODE = "JTabbedPane.tabWidthMode"; @@ -1113,6 +1114,14 @@ public interface FlatClientProperties */ String TABBED_PANE_TAB_WIDTH_MODE_COMPACT = "compact"; + /** + * All tabs are smaller because they show only the tab icon, but no tab title. + * + * @see #TABBED_PANE_TAB_WIDTH_MODE + * @since 3.7 + */ + String TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY = "iconOnly"; + /** * Specifies the tab icon placement (relative to tab title). *

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 83a0abef..07a4c124 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 @@ -205,6 +205,7 @@ public class FlatTabbedPaneUI protected static final int WIDTH_MODE_PREFERRED = 0; protected static final int WIDTH_MODE_EQUAL = 1; protected static final int WIDTH_MODE_COMPACT = 2; + /** @since 3.7 */ protected static final int WIDTH_MODE_ICON_ONLY = 3; // tab rotation /** @since 3.3 */ protected static final int NONE = -1; @@ -780,6 +781,7 @@ public class FlatTabbedPaneUI case WIDTH_MODE_PREFERRED: return TABBED_PANE_TAB_WIDTH_MODE_PREFERRED; case WIDTH_MODE_EQUAL: return TABBED_PANE_TAB_WIDTH_MODE_EQUAL; case WIDTH_MODE_COMPACT: return TABBED_PANE_TAB_WIDTH_MODE_COMPACT; + case WIDTH_MODE_ICON_ONLY: return TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY; } case "tabRotation": @@ -926,9 +928,10 @@ public class FlatTabbedPaneUI int tabWidth; Icon icon; - if( tabWidthMode == WIDTH_MODE_COMPACT && - tabIndex != tabPane.getSelectedIndex() && - isHorizontalOrRotated( tabPlacement ) && + if( ((tabWidthMode == WIDTH_MODE_COMPACT && + tabIndex != tabPane.getSelectedIndex() && + isHorizontalOrRotated( tabPlacement )) || + tabWidthMode == WIDTH_MODE_ICON_ONLY) && tabPane.getTabComponentAt( tabIndex ) == null && (icon = getIconForTab( tabIndex )) != null ) { @@ -1247,7 +1250,8 @@ public class FlatTabbedPaneUI Font font = tabPane.getFont(); FontMetrics metrics = tabPane.getFontMetrics( font ); boolean isCompact = (icon != null && !isSelected && getTabWidthMode() == WIDTH_MODE_COMPACT && isHorizontalOrRotated( tabPlacement )); - if( isCompact ) + boolean isIconOnly = (icon != null && getTabWidthMode() == WIDTH_MODE_ICON_ONLY); + if( isCompact || isIconOnly ) title = null; String clippedTitle = layoutAndClipLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected ); @@ -1283,7 +1287,7 @@ debug*/ } // paint title and icon - if( !isCompact ) + if( !isCompact || isIconOnly ) paintText( g, tabPlacement, font, metrics, tabIndex, clippedTitle, textRect, isSelected ); paintIcon( g, tabPlacement, tabIndex, icon, iconRect, isSelected ); } @@ -2160,6 +2164,7 @@ debug*/ case TABBED_PANE_TAB_WIDTH_MODE_PREFERRED: return WIDTH_MODE_PREFERRED; case TABBED_PANE_TAB_WIDTH_MODE_EQUAL: return WIDTH_MODE_EQUAL; case TABBED_PANE_TAB_WIDTH_MODE_COMPACT: return WIDTH_MODE_COMPACT; + case TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY: return WIDTH_MODE_ICON_ONLY; } } @@ -2508,7 +2513,7 @@ debug*/ // 2. text of label or text component in custom tab component (including children) // 3. accessible name of tab // 4. accessible name of custom tab component (including children) - // 5. string "n. Tab" + // 5. string "n. Tab", if tab does not have an icon String title = tabPane.getTitleAt( tabIndex ); if( StringUtils.isEmpty( title ) ) { Component tabComp = tabPane.getTabComponentAt( tabIndex ); @@ -2518,7 +2523,7 @@ debug*/ title = tabPane.getAccessibleContext().getAccessibleChild( tabIndex ).getAccessibleContext().getAccessibleName(); if( StringUtils.isEmpty( title ) && tabComp instanceof Accessible ) title = findTabTitleInAccessible( (Accessible) tabComp ); - if( StringUtils.isEmpty( title ) ) + if( StringUtils.isEmpty( title ) && tabPane.getIconAt( tabIndex ) == null ) title = (tabIndex + 1) + ". Tab"; } @@ -2539,6 +2544,12 @@ debug*/ if( !tabPane.isEnabled() || !tabPane.isEnabledAt( tabIndex ) ) menuItem.setEnabled( false ); + // make menu item smaller if it contains icon only + if( StringUtils.isEmpty( title ) ) { + menuItem.putClientProperty( FlatClientProperties.STYLE, + "minimumWidth: 0; textNoAcceleratorGap: 0; acceleratorArrowGap: 0" ); + } + menuItem.addActionListener( e -> selectTab( tabIndex ) ); return menuItem; } 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 368562b1..7164ed02 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -696,7 +696,7 @@ TabbedPane.hiddenTabsNavigation = moreTabsButton TabbedPane.tabAreaAlignment = leading # allowed values: leading, trailing or center TabbedPane.tabAlignment = center -# allowed values: preferred, equal or compact +# allowed values: preferred, equal, compact or iconsOnly TabbedPane.tabWidthMode = preferred # allowed values: none, auto, left or right TabbedPane.tabRotation = none diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java index d2251c06..fa58e42d 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java @@ -69,6 +69,7 @@ class TabsPanel initTabWidthMode( widthPreferredTabbedPane, TABBED_PANE_TAB_WIDTH_MODE_PREFERRED ); initTabWidthMode( widthEqualTabbedPane, TABBED_PANE_TAB_WIDTH_MODE_EQUAL ); initTabWidthMode( widthCompactTabbedPane, TABBED_PANE_TAB_WIDTH_MODE_COMPACT ); + initTabWidthMode( widthIconOnlyTabbedPane, TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY ); } private void initTabPlacementTabs( JTabbedPane tabbedPane ) { @@ -262,7 +263,9 @@ class TabsPanel private void initTabWidthMode( JTabbedPane tabbedPane, String tabWidthMode ) { tabbedPane.putClientProperty( TABBED_PANE_TAB_WIDTH_MODE, tabWidthMode ); - if( tabWidthMode.equals( TABBED_PANE_TAB_WIDTH_MODE_COMPACT ) ) { + if( tabWidthMode.equals( TABBED_PANE_TAB_WIDTH_MODE_COMPACT ) || + tabWidthMode.equals( TABBED_PANE_TAB_WIDTH_MODE_ICON_ONLY ) ) + { tabbedPane.addTab( "Search", new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/search.svg", 16, 16 ), null ); tabbedPane.addTab( "Recents", new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/RecentlyUsed.svg", 16, 16 ), null ); tabbedPane.addTab( "Favorites", new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/favorite.svg", 16, 16 ), null ); @@ -390,6 +393,7 @@ class TabsPanel widthPreferredTabbedPane = new JTabbedPane(); widthEqualTabbedPane = new JTabbedPane(); widthCompactTabbedPane = new JTabbedPane(); + widthIconOnlyTabbedPane = new JTabbedPane(); JLabel minMaxTabWidthLabel = new JLabel(); minimumTabWidthTabbedPane = new JTabbedPane(); maximumTabWidthTabbedPane = new JTabbedPane(); @@ -684,6 +688,7 @@ class TabsPanel "[]" + "[]" + "[]" + + "[]" + "[]para" + "[]" + "[]" + @@ -697,25 +702,56 @@ class TabsPanel panel3.add(tabWidthModeLabel, "cell 0 0"); //---- tabWidthModeNoteLabel ---- - tabWidthModeNoteLabel.setText("(preferred/equal/compact)"); + tabWidthModeNoteLabel.setText("(preferred/equal/compact/iconOnly)"); tabWidthModeNoteLabel.setEnabled(false); tabWidthModeNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small"); panel3.add(tabWidthModeNoteLabel, "cell 0 1"); + + //======== widthPreferredTabbedPane ======== + { + widthPreferredTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel3.add(widthPreferredTabbedPane, "cell 0 2"); + + //======== widthEqualTabbedPane ======== + { + widthEqualTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel3.add(widthEqualTabbedPane, "cell 0 3"); + + //======== widthCompactTabbedPane ======== + { + widthCompactTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel3.add(widthCompactTabbedPane, "cell 0 4"); + //======== widthIconOnlyTabbedPane ======== + { + widthIconOnlyTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } + panel3.add(widthIconOnlyTabbedPane, "cell 0 5"); + //---- minMaxTabWidthLabel ---- minMaxTabWidthLabel.setText("Minimum/maximum tab width"); minMaxTabWidthLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3"); - panel3.add(minMaxTabWidthLabel, "cell 0 5"); - panel3.add(minimumTabWidthTabbedPane, "cell 0 6"); - panel3.add(maximumTabWidthTabbedPane, "cell 0 7"); + panel3.add(minMaxTabWidthLabel, "cell 0 6"); + + //======== minimumTabWidthTabbedPane ======== + { + minimumTabWidthTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } + panel3.add(minimumTabWidthTabbedPane, "cell 0 7"); + + //======== maximumTabWidthTabbedPane ======== + { + maximumTabWidthTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } + panel3.add(maximumTabWidthTabbedPane, "cell 0 8"); //---- tabAlignmentLabel ---- tabAlignmentLabel.setText("Tab title alignment"); tabAlignmentLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3"); - panel3.add(tabAlignmentLabel, "cell 0 8"); + panel3.add(tabAlignmentLabel, "cell 0 9"); //======== panel5 ======== { @@ -742,17 +778,33 @@ class TabsPanel tabAlignmentNoteLabel2.setEnabled(false); tabAlignmentNoteLabel2.putClientProperty(FlatClientProperties.STYLE_CLASS, "small"); panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0"); + + //======== tabAlignLeadingTabbedPane ======== + { + tabAlignLeadingTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel5.add(tabAlignLeadingTabbedPane, "cell 0 1"); //======== tabAlignVerticalTabbedPane ======== { tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT); + tabAlignVerticalTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); } panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 4,growy"); + + //======== tabAlignCenterTabbedPane ======== + { + tabAlignCenterTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel5.add(tabAlignCenterTabbedPane, "cell 0 2"); + + //======== tabAlignTrailingTabbedPane ======== + { + tabAlignTrailingTabbedPane.putClientProperty(FlatClientProperties.TABBED_PANE_TAB_HEIGHT, 28); + } panel5.add(tabAlignTrailingTabbedPane, "cell 0 3"); } - panel3.add(panel5, "cell 0 9"); + panel3.add(panel5, "cell 0 10"); } panel6.add(panel3, "cell 2 0"); } @@ -1027,6 +1079,7 @@ class TabsPanel private JTabbedPane widthPreferredTabbedPane; private JTabbedPane widthEqualTabbedPane; private JTabbedPane widthCompactTabbedPane; + private JTabbedPane widthIconOnlyTabbedPane; private JTabbedPane minimumTabWidthTabbedPane; private JTabbedPane maximumTabWidthTabbedPane; private JPanel panel5; diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd index aa9a1b16..49371908 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8" +JFDML JFormDesigner: "8.3" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -337,7 +337,7 @@ new FormModel { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$layoutConstraints": "insets 0,hidemode 3" "$columnConstraints": "[grow,fill]" - "$rowConstraints": "[]0[][][][]para[][][]para[]0[]" + "$rowConstraints": "[]0[][][][][]para[][][]para[]0[]" } ) { name: "panel3" auxiliary() { @@ -355,7 +355,7 @@ new FormModel { } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "tabWidthModeNoteLabel" - "text": "(preferred/equal/compact)" + "text": "(preferred/equal/compact/iconOnly)" "enabled": false "$client.FlatLaf.styleClass": "small" auxiliary() { @@ -366,19 +366,28 @@ new FormModel { } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "widthPreferredTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "widthEqualTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 3" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "widthCompactTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 4" } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "widthIconOnlyTabbedPane" + "$client.JTabbedPane.tabHeight": 28 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "minMaxTabWidthLabel" "text": "Minimum/maximum tab width" @@ -386,19 +395,21 @@ new FormModel { auxiliary() { "JavaCodeGenerator.variableLocal": true } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 5" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "minimumTabWidthTabbedPane" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 6" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "maximumTabWidthTabbedPane" + name: "minimumTabWidthTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 7" } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "maximumTabWidthTabbedPane" + "$client.JTabbedPane.tabHeight": 28 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 8" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "tabAlignmentLabel" "text": "Tab title alignment" @@ -407,7 +418,7 @@ new FormModel { "JavaCodeGenerator.variableLocal": true } }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 8" + "value": "cell 0 9" } ) add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { "$columnConstraints": "[grow,fill]para[fill]" @@ -439,27 +450,31 @@ new FormModel { } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "tabAlignLeadingTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "tabAlignVerticalTabbedPane" "tabPlacement": 2 + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1 1 4,growy" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "tabAlignCenterTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "tabAlignTrailingTabbedPane" + "$client.JTabbedPane.tabHeight": 28 }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 3" } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 9" + "value": "cell 0 10" } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 0" diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java index 5dadf2bd..844c6d0e 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java @@ -484,7 +484,7 @@ public class FlatTabbedPane // NOTE: enum names must be equal to allowed strings - public enum TabWidthMode { preferred, equal, compact } + public enum TabWidthMode { preferred, equal, compact, /** @since 3.7 */ iconOnly } /** * Returns how the tabs should be sized.