TabbedPane: support hiding tab area if it contains only one tab

This commit is contained in:
Karl Tauber
2020-11-28 11:21:46 +01:00
parent 21a12b8dd4
commit d0ffc4f979
5 changed files with 67 additions and 4 deletions

View File

@@ -10,7 +10,8 @@ FlatLaf Change Log
- Added "Gradianto Nature Green" theme. - Added "Gradianto Nature Green" theme.
- Updated "Arc Dark", "Cyan", "Dark purple", "Gradianto", "Gray", "Gruvbox" - Updated "Arc Dark", "Cyan", "Dark purple", "Gradianto", "Gray", "Gruvbox"
and "One Dark" themes. and "One Dark" themes.
- TabbedPane: Support hiding tab area if it contains only one tab. (set client
property `JTabbedPane.hideTabAreaWithOneTab` to `true`)
#### Fixed bugs #### Fixed bugs

View File

@@ -219,7 +219,7 @@ public interface FlatClientProperties
*/ */
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded"; String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
//---- JScrollBar --------------------------------------------------------- //---- JScrollBar / JScrollPane -------------------------------------------
/** /**
* Specifies whether the decrease/increase arrow buttons of a scrollbar are shown. * Specifies whether the decrease/increase arrow buttons of a scrollbar are shown.
@@ -263,6 +263,14 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder"; String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder";
/**
* Specifies whether the tab area should be hidded if it contains only one tab.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.Boolean}
*/
String TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB = "JTabbedPane.hideTabAreaWithOneTab";
/** /**
* Specifies the minimum width of a tab. * Specifies the minimum width of a tab.
* <p> * <p>

View File

@@ -693,6 +693,26 @@ public class FlatTabbedPaneUI
return Math.max( tabHeight, scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ) ) ); return Math.max( tabHeight, scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ) ) );
} }
@Override
protected int calculateMaxTabWidth( int tabPlacement ) {
return hideTabArea() ? 0 : super.calculateMaxTabWidth( tabPlacement );
}
@Override
protected int calculateMaxTabHeight( int tabPlacement ) {
return hideTabArea() ? 0 : super.calculateMaxTabHeight( tabPlacement );
}
@Override
protected int calculateTabAreaWidth( int tabPlacement, int vertRunCount, int maxTabWidth ) {
return hideTabArea() ? 0 : super.calculateTabAreaWidth( tabPlacement, vertRunCount, maxTabWidth );
}
@Override
protected int calculateTabAreaHeight( int tabPlacement, int horizRunCount, int maxTabHeight ) {
return hideTabArea() ? 0 : super.calculateTabAreaHeight( tabPlacement, horizRunCount, maxTabHeight );
}
@Override @Override
protected Insets getTabInsets( int tabPlacement, int tabIndex ) { protected Insets getTabInsets( int tabPlacement, int tabIndex ) {
Object value = getTabClientProperty( tabIndex, TABBED_PANE_TAB_INSETS ); Object value = getTabClientProperty( tabIndex, TABBED_PANE_TAB_INSETS );
@@ -752,7 +772,7 @@ public class FlatTabbedPaneUI
*/ */
@Override @Override
protected Insets getContentBorderInsets( int tabPlacement ) { protected Insets getContentBorderInsets( int tabPlacement ) {
if( contentSeparatorHeight == 0 || !clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) ) if( hideTabArea() || contentSeparatorHeight == 0 || !clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
return new Insets( 0, 0, 0, 0 ); return new Insets( 0, 0, 0, 0 );
boolean hasFullBorder = clientPropertyBoolean( tabPane, TABBED_PANE_HAS_FULL_BORDER, this.hasFullBorder ); boolean hasFullBorder = clientPropertyBoolean( tabPane, TABBED_PANE_HAS_FULL_BORDER, this.hasFullBorder );
@@ -787,6 +807,9 @@ public class FlatTabbedPaneUI
@Override @Override
public void paint( Graphics g, JComponent c ) { public void paint( Graphics g, JComponent c ) {
if( hideTabArea() )
return;
ensureCurrentLayout(); ensureCurrentLayout();
int tabPlacement = tabPane.getTabPlacement(); int tabPlacement = tabPane.getTabPlacement();
@@ -1226,6 +1249,13 @@ public class FlatTabbedPaneUI
return UIManager.getBoolean( "ScrollPane.smoothScrolling" ); return UIManager.getBoolean( "ScrollPane.smoothScrolling" );
} }
protected boolean hideTabArea() {
return tabPane.getTabCount() == 1 &&
leadingComponent == null &&
trailingComponent == null &&
clientPropertyBoolean( tabPane, TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, false );
}
protected int getTabsPopupPolicy() { protected int getTabsPopupPolicy() {
Object value = tabPane.getClientProperty( TABBED_PANE_TABS_POPUP_POLICY ); Object value = tabPane.getClientProperty( TABBED_PANE_TABS_POPUP_POLICY );
@@ -2193,6 +2223,7 @@ public class FlatTabbedPaneUI
case TABBED_PANE_SHOW_TAB_SEPARATORS: case TABBED_PANE_SHOW_TAB_SEPARATORS:
case TABBED_PANE_SHOW_CONTENT_SEPARATOR: case TABBED_PANE_SHOW_CONTENT_SEPARATOR:
case TABBED_PANE_HAS_FULL_BORDER: case TABBED_PANE_HAS_FULL_BORDER:
case TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB:
case TABBED_PANE_MINIMUM_TAB_WIDTH: case TABBED_PANE_MINIMUM_TAB_WIDTH:
case TABBED_PANE_MAXIMUM_TAB_WIDTH: case TABBED_PANE_MAXIMUM_TAB_WIDTH:
case TABBED_PANE_TAB_HEIGHT: case TABBED_PANE_TAB_HEIGHT:

View File

@@ -78,6 +78,11 @@ public class FlatContainerTest
putTabbedPanesClientProperty( TABBED_PANE_SHOW_CONTENT_SEPARATOR, showContentSeparator ); putTabbedPanesClientProperty( TABBED_PANE_SHOW_CONTENT_SEPARATOR, showContentSeparator );
} }
private void hideTabAreaWithOneTabChanged() {
boolean hideTabAreaWithOneTab = hideTabAreaWithOneTabCheckBox.isSelected();
putTabbedPanesClientProperty( TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, hideTabAreaWithOneTab );
}
private void hasFullBorderChanged() { private void hasFullBorderChanged() {
Boolean hasFullBorder = hasFullBorderCheckBox.isSelected() ? true : null; Boolean hasFullBorder = hasFullBorderCheckBox.isSelected() ? true : null;
putTabbedPanesClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder ); putTabbedPanesClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder );
@@ -461,6 +466,7 @@ public class FlatContainerTest
maximumTabWidthCheckBox = new JCheckBox(); maximumTabWidthCheckBox = new JCheckBox();
showTabSeparatorsCheckBox = new JCheckBox(); showTabSeparatorsCheckBox = new JCheckBox();
secondTabWiderCheckBox = new JCheckBox(); secondTabWiderCheckBox = new JCheckBox();
hideTabAreaWithOneTabCheckBox = new JCheckBox();
CellConstraints cc = new CellConstraints(); CellConstraints cc = new CellConstraints();
//======== this ======== //======== this ========
@@ -579,6 +585,7 @@ public class FlatContainerTest
"[]" + "[]" +
"[]para" + "[]para" +
"[]" + "[]" +
"[]" +
"[]")); "[]"));
//---- tabScrollCheckBox ---- //---- tabScrollCheckBox ----
@@ -800,6 +807,11 @@ public class FlatContainerTest
secondTabWiderCheckBox.setText("Second Tab insets wider (4,20,4,20)"); secondTabWiderCheckBox.setText("Second Tab insets wider (4,20,4,20)");
secondTabWiderCheckBox.addActionListener(e -> secondTabWiderChanged()); secondTabWiderCheckBox.addActionListener(e -> secondTabWiderChanged());
tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 9"); tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 9");
//---- hideTabAreaWithOneTabCheckBox ----
hideTabAreaWithOneTabCheckBox.setText("Hide tab area with one tab");
hideTabAreaWithOneTabCheckBox.addActionListener(e -> hideTabAreaWithOneTabChanged());
tabbedPaneControlPanel.add(hideTabAreaWithOneTabCheckBox, "cell 1 10");
} }
panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1)); panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1));
} }
@@ -844,6 +856,7 @@ public class FlatContainerTest
private JCheckBox maximumTabWidthCheckBox; private JCheckBox maximumTabWidthCheckBox;
private JCheckBox showTabSeparatorsCheckBox; private JCheckBox showTabSeparatorsCheckBox;
private JCheckBox secondTabWiderCheckBox; private JCheckBox secondTabWiderCheckBox;
private JCheckBox hideTabAreaWithOneTabCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
private JTabbedPane[] allTabbedPanes; private JTabbedPane[] allTabbedPanes;

View File

@@ -132,7 +132,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestFrame$NoRightToLeftPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestFrame$NoRightToLeftPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3" "$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[][fill][]" "$columnConstraints": "[][fill][]"
"$rowConstraints": "[center][][][][][]para[][]para[][]" "$rowConstraints": "[center][][][][][]para[][]para[][][]"
} ) { } ) {
name: "tabbedPaneControlPanel" name: "tabbedPaneControlPanel"
"opaque": false "opaque": false
@@ -547,6 +547,16 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 9" "value": "cell 2 9"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hideTabAreaWithOneTabCheckBox"
"text": "Hide tab area with one tab"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideTabAreaWithOneTabChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10"
} )
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
"gridY": 11 "gridY": 11
"gridWidth": 3 "gridWidth": 3