From c0408045efd99b27486f1c770a0174fe04bcce10 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 15 Oct 2020 10:41:45 +0200 Subject: [PATCH] TabbedPane: support specifying hiddenTabsNavigation type per tabbedpane via client property (issue #40) --- .../formdev/flatlaf/FlatClientProperties.java | 24 +++++++++++++ .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 35 +++++++++++++------ .../flatlaf/testing/FlatContainerTest.java | 33 +++++++++++++++-- .../flatlaf/testing/FlatContainerTest.jfd | 22 ++++++++++++ 4 files changed, 101 insertions(+), 13 deletions(-) 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 05183459..3ad1dd8f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -240,6 +240,30 @@ public interface FlatClientProperties */ String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight"; + /** + * Specifies how to navigate to 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} + */ + String TABBED_PANE_HIDDEN_TABS_NAVIGATION = "JTabbedPane.hiddenTabsNavigation"; + + /** + * Use "more tabs" button for navigation to hidden tabs. + * + * @see #TABBED_PANE_HIDDEN_TABS_NAVIGATION + */ + String TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON = "moreTabsButton"; + + /** + * Use forward/backward buttons for navigation to hidden tabs. + * + * @see #TABBED_PANE_HIDDEN_TABS_NAVIGATION + */ + String TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS = "arrowButtons"; + /** * Specifies whether all text is selected when the text component gains focus. *

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 20f7579b..f8df3d51 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 @@ -268,13 +268,27 @@ public class FlatTabbedPaneUI } } - // initialize here because used in installHiddenTabsNavigation() before installDefaults() was invoked - hiddenTabsNavigation = parseHiddenTabsNavigation( UIManager.getString( "TabbedPane.hiddenTabsNavigation" ) ); - installHiddenTabsNavigation(); } - private void installHiddenTabsNavigation() { + @Override + protected void uninstallComponents() { + // uninstall hidden tabs navigation before invoking super.uninstallComponents() for + // correct uninstallation of BasicTabbedPaneUI tab scroller support + uninstallHiddenTabsNavigation(); + + super.uninstallComponents(); + + tabViewport = null; + } + + protected void installHiddenTabsNavigation() { + // initialize here because used in installHiddenTabsNavigation() before installDefaults() was invoked + String hiddenTabsNavigationStr = (String) tabPane.getClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION ); + if( hiddenTabsNavigationStr == null ) + hiddenTabsNavigationStr = UIManager.getString( "TabbedPane.hiddenTabsNavigation" ); + hiddenTabsNavigation = parseHiddenTabsNavigation( hiddenTabsNavigationStr ); + if( hiddenTabsNavigation != MORE_TABS_BUTTON || !isScrollTabLayout() || tabViewport == null ) @@ -293,21 +307,16 @@ public class FlatTabbedPaneUI tabPane.add( moreTabsButton ); } - @Override - protected void uninstallComponents() { + protected void uninstallHiddenTabsNavigation() { // restore layout manager before invoking super.uninstallComponents() for // correct uninstallation of BasicTabbedPaneUI tab scroller support if( tabPane.getLayout() instanceof FlatTabbedPaneScrollLayout ) tabPane.setLayout( ((FlatTabbedPaneScrollLayout)tabPane.getLayout()).delegate ); - super.uninstallComponents(); - if( moreTabsButton != null ) { tabPane.remove( moreTabsButton ); moreTabsButton = null; } - - tabViewport = null; } @Override @@ -1276,6 +1285,12 @@ public class FlatTabbedPaneUI tabPane.revalidate(); tabPane.repaint(); break; + + case TABBED_PANE_HIDDEN_TABS_NAVIGATION: + uninstallHiddenTabsNavigation(); + installHiddenTabsNavigation(); + tabPane.repaint(); + break; } } 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 ad631094..6120407c 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 @@ -16,9 +16,7 @@ package com.formdev.flatlaf.testing; -import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER; -import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_CONTENT_SEPARATOR; -import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPARATORS; +import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.*; import javax.swing.*; import javax.swing.border.*; @@ -230,6 +228,19 @@ public class FlatContainerTest tabbedPane4.setTabPlacement( (tabPlacement >= 0) ? tabPlacement : SwingConstants.RIGHT ); } + private void hiddenTabsNavigationChanged() { + String value = null; + switch( (String) hiddenTabsNavigationField.getSelectedItem() ) { + case "moreTabsButton": value = TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON; break; + case "arrowButtons": value = TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS; break; + } + + tabbedPane1.putClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value ); + tabbedPane2.putClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value ); + tabbedPane3.putClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value ); + tabbedPane4.putClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value ); + } + private void tabBackForegroundChanged() { boolean enabled = tabBackForegroundCheckBox.isSelected(); tabbedPane1.setBackgroundAt( 0, enabled ? Color.red : null ); @@ -267,6 +278,8 @@ public class FlatContainerTest hasFullBorderCheckBox = new JCheckBox(); JLabel tabPlacementLabel = new JLabel(); tabPlacementField = new JComboBox<>(); + JLabel hiddenTabsNavigationLabel = new JLabel(); + hiddenTabsNavigationField = new JComboBox<>(); tabBackForegroundCheckBox = new JCheckBox(); CellConstraints cc = new CellConstraints(); @@ -452,6 +465,19 @@ public class FlatContainerTest tabPlacementField.addActionListener(e -> tabPlacementChanged()); panel14.add(tabPlacementField, "cell 1 2"); + //---- hiddenTabsNavigationLabel ---- + hiddenTabsNavigationLabel.setText("Hidden tabs navigation:"); + panel14.add(hiddenTabsNavigationLabel, "cell 2 2"); + + //---- hiddenTabsNavigationField ---- + hiddenTabsNavigationField.setModel(new DefaultComboBoxModel<>(new String[] { + "default", + "moreTabsButton", + "arrowButtons" + })); + hiddenTabsNavigationField.addActionListener(e -> hiddenTabsNavigationChanged()); + panel14.add(hiddenTabsNavigationField, "cell 3 2"); + //---- tabBackForegroundCheckBox ---- tabBackForegroundCheckBox.setText("Tab back/foreground"); tabBackForegroundCheckBox.addActionListener(e -> tabBackForegroundChanged()); @@ -479,6 +505,7 @@ public class FlatContainerTest private JCheckBox customTabsCheckBox; private JCheckBox hasFullBorderCheckBox; private JComboBox tabPlacementField; + private JComboBox hiddenTabsNavigationField; private JCheckBox tabBackForegroundCheckBox; // JFormDesigner - End of variables declaration //GEN-END:variables diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd index 437bfa6f..4e481d5b 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd @@ -275,6 +275,28 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 2" } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "hiddenTabsNavigationLabel" + "text": "Hidden tabs navigation:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 2" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "hiddenTabsNavigationField" + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "default" + addElement( "default" ) + addElement( "moreTabsButton" ) + addElement( "arrowButtons" ) + } + auxiliary() { + "JavaCodeGenerator.variableLocal": false + "JavaCodeGenerator.typeParameters": "String" + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hiddenTabsNavigationChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 2" + } ) add( new FormComponent( "javax.swing.JCheckBox" ) { name: "tabBackForegroundCheckBox" "text": "Tab back/foreground"