Merge pull request #199 into master

TabbedPane: tab area alignment; min/max tab widths; tab icon placement; tab width mode
This commit is contained in:
Karl Tauber
2020-11-01 15:56:10 +01:00
11 changed files with 971 additions and 272 deletions

View File

@@ -19,6 +19,19 @@ FlatLaf Change Log
`JTabbedPane.trailingComponent` to a `java.awt.Component`) (PR #192; issue `JTabbedPane.trailingComponent` to a `java.awt.Component`) (PR #192; issue
#40) #40)
- TabbedPane: Support closable tabs. (PR #193; issues #31 and #40) - TabbedPane: Support closable tabs. (PR #193; issues #31 and #40)
- TabbedPane: Support minimum or maximum tab widths. (set client property
`JTabbedPane.minimumTabWidth` or `JTabbedPane.maximumTabWidth` to an integer)
(PR #199)
- TabbedPane: Support alignment of tab area. (set client property
`JTabbedPane.tabAreaAlignment` to `"leading"`, `"trailing"`, `"center"` or
`"fill"`) (PR #199)
- TabbedPane: Support equal and compact tab width modes. (set client property
`JTabbedPane.tabWidthMode` to `"preferred"`, `"equal"` or `"compact"`) (PR
#199)
- TabbedPane: Support left, right, top and bottom tab icon placement. (set
client property `JTabbedPane.tabIconPlacement` to `SwingConstants.LEADING`,
`SwingConstants.TRAILING`, `SwingConstants.TOP` or `SwingConstants.BOTTOM`)
(PR #199)
- Support painting separator line between window title and content (use UI value - Support painting separator line between window title and content (use UI value
`TitlePane.borderColor`). (issue #184) `TitlePane.borderColor`). (issue #184)
- Extras: `FlatSVGIcon` now allows specifying icon width and height in - Extras: `FlatSVGIcon` now allows specifying icon width and height in

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf;
import java.awt.Color; import java.awt.Color;
import java.util.Objects; import java.util.Objects;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.SwingConstants;
/** /**
* @author Karl Tauber * @author Karl Tauber
@@ -101,7 +102,7 @@ public interface FlatClientProperties
/** /**
* Specifies whether the button preferred size will be made square (quadratically). * Specifies whether the button preferred size will be made square (quadratically).
* <p> * <p>
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton} * <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
* <strong>Value type</strong> {@link java.lang.Boolean} * <strong>Value type</strong> {@link java.lang.Boolean}
*/ */
String SQUARE_SIZE = "JButton.squareSize"; String SQUARE_SIZE = "JButton.squareSize";
@@ -113,7 +114,7 @@ public interface FlatClientProperties
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JButton}, {@link javax.swing.JToggleButton}, * <strong>Component</strong> {@link javax.swing.JButton}, {@link javax.swing.JToggleButton},
* {@link javax.swing.JComboBox}, {@link javax.swing.JSpinner} and {@link javax.swing.text.JTextComponent}<br> * {@link javax.swing.JComboBox}, {@link javax.swing.JSpinner} and {@link javax.swing.text.JTextComponent}<br>
* <strong>Value type</strong> {@link java.lang.Integer}<br> * <strong>Value type</strong> {@link java.lang.Integer}
*/ */
String MINIMUM_WIDTH = "JComponent.minimumWidth"; String MINIMUM_WIDTH = "JComponent.minimumWidth";
@@ -121,7 +122,7 @@ public interface FlatClientProperties
* Specifies minimum height of a component. * Specifies minimum height of a component.
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br> * <strong>Component</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
* <strong>Value type</strong> {@link java.lang.Integer}<br> * <strong>Value type</strong> {@link java.lang.Integer}
*/ */
String MINIMUM_HEIGHT = "JComponent.minimumHeight"; String MINIMUM_HEIGHT = "JComponent.minimumHeight";
@@ -157,7 +158,7 @@ public interface FlatClientProperties
* Paint the component with round edges. * Paint the component with round edges.
* <p> * <p>
* <strong>Components</strong> {@link javax.swing.JComboBox}, {@link javax.swing.JSpinner}, * <strong>Components</strong> {@link javax.swing.JComboBox}, {@link javax.swing.JSpinner},
* {@link javax.swing.JTextField}, {@link javax.swing.JFormattedTextField} and {@link javax.swing.JPasswordField} * {@link javax.swing.JTextField}, {@link javax.swing.JFormattedTextField} and {@link javax.swing.JPasswordField}<br>
* <strong>Value type</strong> {@link java.lang.Boolean} * <strong>Value type</strong> {@link java.lang.Boolean}
*/ */
String COMPONENT_ROUND_RECT = "JComponent.roundRect"; String COMPONENT_ROUND_RECT = "JComponent.roundRect";
@@ -246,6 +247,27 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder"; String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder";
/**
* Specifies the minimum width of a tab.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}
* or tab content components (see {@link javax.swing.JTabbedPane#setComponentAt(int, java.awt.Component)})<br>
* <strong>Value type</strong> {@link java.lang.Integer}
*/
String TABBED_PANE_MINIMUM_TAB_WIDTH = "JTabbedPane.minimumTabWidth";
/**
* Specifies the maximum width of a tab.
* <p>
* Applied only if tab does not have a custom tab component
* (see {@link javax.swing.JTabbedPane#setTabComponentAt(int, java.awt.Component)}).
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}
* or tab content components (see {@link javax.swing.JTabbedPane#setComponentAt(int, java.awt.Component)})<br>
* <strong>Value type</strong> {@link java.lang.Integer}
*/
String TABBED_PANE_MAXIMUM_TAB_WIDTH = "JTabbedPane.maximumTabWidth";
/** /**
* Specifies the height of a tab. * Specifies the height of a tab.
* <p> * <p>
@@ -263,6 +285,14 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_TAB_INSETS = "JTabbedPane.tabInsets"; String TABBED_PANE_TAB_INSETS = "JTabbedPane.tabInsets";
/**
* Specifies the insets of the tab area.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.awt.Insets}
*/
String TABBED_PANE_TAB_AREA_INSETS = "JTabbedPane.tabAreaInsets";
/** /**
* Specifies whether tabs are closable. * Specifies whether tabs are closable.
* If set to {@code true} on a tabbed pane component, all tabs in that tabbed pane are closable. * If set to {@code true} on a tabbed pane component, all tabs in that tabbed pane are closable.
@@ -330,7 +360,7 @@ public interface FlatClientProperties
* Specifies how to navigate to hidden tabs. * Specifies how to navigate to hidden tabs.
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br> * <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.String} * <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong> {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON} * <strong>Allowed Values</strong> {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON}
* or {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS} * or {@link #TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS}
*/ */
@@ -350,6 +380,88 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS = "arrowButtons"; String TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS = "arrowButtons";
/**
* Specifies the alignment of the tab area.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong> {@link #TABBED_PANE_TAB_AREA_ALIGN_LEADING} (default),
* {@link #TABBED_PANE_TAB_AREA_ALIGN_TRAILING}, {@link #TABBED_PANE_TAB_AREA_ALIGN_CENTER}
* or {@link #TABBED_PANE_TAB_AREA_ALIGN_FILL}
*/
String TABBED_PANE_TAB_AREA_ALIGNMENT = "JTabbedPane.tabAreaAlignment";
/**
* Align the tab area to the leading edge.
*
* @see #TABBED_PANE_TAB_AREA_ALIGNMENT
*/
String TABBED_PANE_TAB_AREA_ALIGN_LEADING = "leading";
/**
* Align the tab area to the trailing edge.
*
* @see #TABBED_PANE_TAB_AREA_ALIGNMENT
*/
String TABBED_PANE_TAB_AREA_ALIGN_TRAILING = "trailing";
/**
* Align the tab area to center.
*
* @see #TABBED_PANE_TAB_AREA_ALIGNMENT
*/
String TABBED_PANE_TAB_AREA_ALIGN_CENTER = "center";
/**
* Stretch tabs to fill all available space.
*
* @see #TABBED_PANE_TAB_AREA_ALIGNMENT
*/
String TABBED_PANE_TAB_AREA_ALIGN_FILL = "fill";
/**
* Specifies how the tabs should be sized.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong> {@link #TABBED_PANE_TAB_WIDTH_MODE_PREFERRED} (default),
* {@link #TABBED_PANE_TAB_WIDTH_MODE_EQUAL} or {@link #TABBED_PANE_TAB_WIDTH_MODE_COMPACT}
*/
String TABBED_PANE_TAB_WIDTH_MODE = "JTabbedPane.tabWidthMode";
/**
* Tab width is adjusted to tab icon and title.
*
* @see #TABBED_PANE_TAB_WIDTH_MODE
*/
String TABBED_PANE_TAB_WIDTH_MODE_PREFERRED = "preferred";
/**
* All tabs in a tabbed pane has same width.
*
* @see #TABBED_PANE_TAB_WIDTH_MODE
*/
String TABBED_PANE_TAB_WIDTH_MODE_EQUAL = "equal";
/**
* Unselected tabs are smaller because they show only the tab icon, but no tab title.
* Selected tabs show both.
*
* @see #TABBED_PANE_TAB_WIDTH_MODE
*/
String TABBED_PANE_TAB_WIDTH_MODE_COMPACT = "compact";
/**
* Specifies the tab icon placement (relative to tab title).
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.Integer}<br>
* <strong>Allowed Values</strong> {@link SwingConstants#LEADING} (default),
* {@link SwingConstants#TRAILING}, {@link SwingConstants#TOP}
* or {@link SwingConstants#BOTTOM}
*/
String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement";
/** /**
* Specifies a component that will be placed at the leading edge of the tabs area. * Specifies a component that will be placed at the leading edge of the tabs area.
* <p> * <p>

View File

@@ -118,6 +118,8 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.focusColor Color * @uiDefault TabbedPane.focusColor Color
* @uiDefault TabbedPane.tabSeparatorColor Color optional; defaults to TabbedPane.contentAreaColor * @uiDefault TabbedPane.tabSeparatorColor Color optional; defaults to TabbedPane.contentAreaColor
* @uiDefault TabbedPane.contentAreaColor Color * @uiDefault TabbedPane.contentAreaColor Color
* @uiDefault TabbedPane.minimumTabWidth int optional
* @uiDefault TabbedPane.maximumTabWidth int optional
* @uiDefault TabbedPane.tabHeight int * @uiDefault TabbedPane.tabHeight int
* @uiDefault TabbedPane.tabSelectionHeight int * @uiDefault TabbedPane.tabSelectionHeight int
* @uiDefault TabbedPane.contentSeparatorHeight int * @uiDefault TabbedPane.contentSeparatorHeight int
@@ -125,6 +127,8 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean * @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
* @uiDefault TabbedPane.hasFullBorder boolean * @uiDefault TabbedPane.hasFullBorder boolean
* @uiDefault TabbedPane.hiddenTabsNavigation String moreTabsButton (default) or arrowButtons * @uiDefault TabbedPane.hiddenTabsNavigation String moreTabsButton (default) or arrowButtons
* @uiDefault TabbedPane.tabAreaAlignment String leading (default), center, trailing or fill
* @uiDefault TabbedPane.tabWidthMode String preferred (default), equal or compact
* @uiDefault ScrollPane.smoothScrolling boolean * @uiDefault ScrollPane.smoothScrolling boolean
* @uiDefault TabbedPane.closeIcon Icon * @uiDefault TabbedPane.closeIcon Icon
* *
@@ -139,6 +143,16 @@ public class FlatTabbedPaneUI
protected static final int MORE_TABS_BUTTON = 0; protected static final int MORE_TABS_BUTTON = 0;
protected static final int ARROW_BUTTONS = 1; protected static final int ARROW_BUTTONS = 1;
// tab area alignment
protected static final int ALIGN_LEADING = 0;
protected static final int ALIGN_TRAILING = 1;
protected static final int ALIGN_CENTER = 2;
protected static final int ALIGN_FILL = 3;
protected static final int WIDTH_MODE_PREFERRED = 0;
protected static final int WIDTH_MODE_EQUAL = 1;
protected static final int WIDTH_MODE_COMPACT = 2;
private static Set<KeyStroke> focusForwardTraversalKeys; private static Set<KeyStroke> focusForwardTraversalKeys;
private static Set<KeyStroke> focusBackwardTraversalKeys; private static Set<KeyStroke> focusBackwardTraversalKeys;
@@ -153,14 +167,19 @@ public class FlatTabbedPaneUI
protected Color contentAreaColor; protected Color contentAreaColor;
private int textIconGapUnscaled; private int textIconGapUnscaled;
protected int minimumTabWidth;
protected int maximumTabWidth;
protected int tabHeight; protected int tabHeight;
protected int tabSelectionHeight; protected int tabSelectionHeight;
protected int contentSeparatorHeight; protected int contentSeparatorHeight;
protected boolean showTabSeparators; protected boolean showTabSeparators;
protected boolean tabSeparatorsFullHeight; protected boolean tabSeparatorsFullHeight;
protected boolean hasFullBorder; protected boolean hasFullBorder;
protected boolean tabsOpaque = true;
private String hiddenTabsNavigationStr; private String hiddenTabsNavigationStr;
private String tabAreaAlignmentStr;
private String tabWidthModeStr;
protected Icon closeIcon; protected Icon closeIcon;
protected String moreTabsButtonToolTipText; protected String moreTabsButtonToolTipText;
@@ -217,13 +236,18 @@ public class FlatTabbedPaneUI
contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" ); contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" );
textIconGapUnscaled = UIManager.getInt( "TabbedPane.textIconGap" ); textIconGapUnscaled = UIManager.getInt( "TabbedPane.textIconGap" );
minimumTabWidth = UIManager.getInt( "TabbedPane.minimumTabWidth" );
maximumTabWidth = UIManager.getInt( "TabbedPane.maximumTabWidth" );
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" ); tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" ); tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" ); contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" ); showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" ); tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" ); hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
hiddenTabsNavigationStr = UIManager.getString( "TabbedPane.hiddenTabsNavigation" ); hiddenTabsNavigationStr = UIManager.getString( "TabbedPane.hiddenTabsNavigation" );
tabAreaAlignmentStr = UIManager.getString( "TabbedPane.tabAreaAlignment" );
tabWidthModeStr = UIManager.getString( "TabbedPane.tabWidthMode" );
closeIcon = UIManager.getIcon( "TabbedPane.closeIcon" ); closeIcon = UIManager.getIcon( "TabbedPane.closeIcon" );
Locale l = tabPane.getLocale(); Locale l = tabPane.getLocale();
@@ -512,39 +536,97 @@ public class FlatTabbedPaneUI
tabPane.repaint( r ); tabPane.repaint( r );
} }
private boolean inCalculateEqual;
@Override @Override
protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) { protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) {
int tabWidthMode = getTabWidthMode();
if( tabWidthMode == WIDTH_MODE_EQUAL && isHorizontalTabPlacement() && !inCalculateEqual ) {
inCalculateEqual = true;
try {
return calculateMaxTabWidth( tabPlacement );
} finally {
inCalculateEqual = false;
}
}
// update textIconGap before used in super class // update textIconGap before used in super class
textIconGap = scale( textIconGapUnscaled ); textIconGap = scale( textIconGapUnscaled );
int tabWidth = super.calculateTabWidth( tabPlacement, tabIndex, metrics ) - 3 /* was added by superclass */; int tabWidth;
Icon icon;
if( tabWidthMode == WIDTH_MODE_COMPACT &&
tabIndex != tabPane.getSelectedIndex() &&
isHorizontalTabPlacement() &&
tabPane.getTabComponentAt( tabIndex ) == null &&
(icon = getIconForTab( tabIndex )) != null )
{
Insets tabInsets = getTabInsets( tabPlacement, tabIndex );
tabWidth = icon.getIconWidth() + tabInsets.left + tabInsets.right;
} else {
int iconPlacement = clientPropertyInt( tabPane, TABBED_PANE_TAB_ICON_PLACEMENT, LEADING );
if( (iconPlacement == TOP || iconPlacement == BOTTOM) &&
tabPane.getTabComponentAt( tabIndex ) == null &&
(icon = getIconForTab( tabIndex )) != null )
{
// TOP and BOTTOM icon placement
tabWidth = icon.getIconWidth();
View view = getTextViewForTab( tabIndex );
if( view != null )
tabWidth = Math.max( tabWidth, (int) view.getPreferredSpan( View.X_AXIS ) );
else {
String title = tabPane.getTitleAt( tabIndex );
if( title != null )
tabWidth = Math.max( tabWidth, metrics.stringWidth( title ) );
}
Insets tabInsets = getTabInsets( tabPlacement, tabIndex );
tabWidth += tabInsets.left + tabInsets.right;
} else
tabWidth = super.calculateTabWidth( tabPlacement, tabIndex, metrics ) - 3 /* was added by superclass */;
}
// make tab wider if closable
if( isTabClosable( tabIndex ) ) if( isTabClosable( tabIndex ) )
tabWidth += closeIcon.getIconWidth(); tabWidth += closeIcon.getIconWidth();
// apply minimum and maximum tab width
int min = getTabClientPropertyInt( tabIndex, TABBED_PANE_MINIMUM_TAB_WIDTH, minimumTabWidth );
int max = getTabClientPropertyInt( tabIndex, TABBED_PANE_MAXIMUM_TAB_WIDTH, maximumTabWidth );
if( min > 0 )
tabWidth = Math.max( tabWidth, scale( min ) );
if( max > 0 && tabPane.getTabComponentAt( tabIndex ) == null )
tabWidth = Math.min( tabWidth, scale( max ) );
return tabWidth; return tabWidth;
} }
@Override @Override
protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) { protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) {
int tabHeight = scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ) ); int tabHeight;
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */ );
}
protected int calculateMaxExtrasWidth() { Icon icon;
int width = 0; int iconPlacement = clientPropertyInt( tabPane, TABBED_PANE_TAB_ICON_PLACEMENT, LEADING );
if( leadingComponent != null ) if( (iconPlacement == TOP || iconPlacement == BOTTOM) &&
width = Math.max( width, leadingComponent.getPreferredSize().width ); tabPane.getTabComponentAt( tabIndex ) == null &&
if( trailingComponent != null ) (icon = getIconForTab( tabIndex )) != null )
width = Math.max( width, trailingComponent.getPreferredSize().width ); {
return width; // TOP and BOTTOM icon placement
} tabHeight = icon.getIconHeight();
protected int calculateMaxExtrasHeight() { View view = getTextViewForTab( tabIndex );
int height = 0; if( view != null )
if( leadingComponent != null ) tabHeight += (int) view.getPreferredSpan( View.Y_AXIS ) + scale( textIconGapUnscaled );
height = Math.max( height, leadingComponent.getPreferredSize().height ); else if( tabPane.getTitleAt( tabIndex ) != null )
if( trailingComponent != null ) tabHeight += fontHeight + scale( textIconGapUnscaled );
height = Math.max( height, trailingComponent.getPreferredSize().height );
return height; Insets tabInsets = getTabInsets( tabPlacement, tabIndex );
tabHeight += tabInsets.top + tabInsets.bottom;
} else
tabHeight = super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */;
return Math.max( tabHeight, scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ) ) );
} }
@Override @Override
@@ -560,11 +642,14 @@ public class FlatTabbedPaneUI
return new Insets( 0, 0, 0, 0 ); return new Insets( 0, 0, 0, 0 );
} }
@Override protected Insets getRealTabAreaInsets( int tabPlacement ) {
protected Insets getTabAreaInsets( int tabPlacement ) {
Insets currentTabAreaInsets = super.getTabAreaInsets( tabPlacement ); Insets currentTabAreaInsets = super.getTabAreaInsets( tabPlacement );
Insets insets = (Insets) currentTabAreaInsets.clone(); Insets insets = (Insets) currentTabAreaInsets.clone();
Object value = tabPane.getClientProperty( TABBED_PANE_TAB_AREA_INSETS );
if( value instanceof Insets )
rotateInsets( (Insets) value, insets, tabPlacement );
// This is a "trick" to get rid of the cropped edge: // This is a "trick" to get rid of the cropped edge:
// super.getTabAreaInsets() returns private field BasicTabbedPaneUI.currentTabAreaInsets, // super.getTabAreaInsets() returns private field BasicTabbedPaneUI.currentTabAreaInsets,
// which is also used to translate the origin of the cropped edge in // which is also used to translate the origin of the cropped edge in
@@ -575,21 +660,21 @@ public class FlatTabbedPaneUI
// scale insets (before adding leading/trailing component sizes) // scale insets (before adding leading/trailing component sizes)
insets = scale( insets ); insets = scale( insets );
return insets;
}
@Override
protected Insets getTabAreaInsets( int tabPlacement ) {
Insets insets = getRealTabAreaInsets( tabPlacement );
// increase insets for wrap layout if using leading/trailing components // increase insets for wrap layout if using leading/trailing components
if( tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT ) { if( tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT ) {
if( leadingComponent != null ) { if( isHorizontalTabPlacement() ) {
Dimension leadingSize = leadingComponent.getPreferredSize(); insets.left += getLeadingPreferredWidth();
if( isHorizontalTabPlacement() ) insets.right += getTrailingPreferredWidth();
insets.left += leadingSize.width; } else {
else insets.top += getLeadingPreferredHeight();
insets.top += leadingSize.height; insets.bottom += getTrailingPreferredHeight();
}
if( trailingComponent != null ) {
Dimension trailingSize = trailingComponent.getPreferredSize();
if( isHorizontalTabPlacement() )
insets.right += trailingSize.width;
else
insets.bottom += trailingSize.height;
} }
} }
@@ -649,6 +734,62 @@ public class FlatTabbedPaneUI
paintTabArea( g, tabPlacement, selectedIndex ); paintTabArea( g, tabPlacement, selectedIndex );
} }
@Override
protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect )
{
Rectangle tabRect = rects[tabIndex];
int x = tabRect.x;
int y = tabRect.y;
int w = tabRect.width;
int h = tabRect.height;
boolean isSelected = (tabIndex == tabPane.getSelectedIndex());
// paint background
if( tabsOpaque || tabPane.isOpaque() )
paintTabBackground( g, tabPlacement, tabIndex, x, y, w, h, isSelected );
// paint border
paintTabBorder( g, tabPlacement, tabIndex, x, y, w, h, isSelected );
// paint tab close button
if( isTabClosable( tabIndex ) )
paintTabCloseButton( g, tabIndex, x, y, w, h );
// paint selection indicator
if( isSelected )
paintTabSelection( g, tabPlacement, x, y, w, h );
if( tabPane.getTabComponentAt( tabIndex ) != null )
return;
// layout title and icon
String title = tabPane.getTitleAt( tabIndex );
Icon icon = getIconForTab( tabIndex );
Font font = tabPane.getFont();
FontMetrics metrics = tabPane.getFontMetrics( font );
boolean isCompact = (icon != null && !isSelected && getTabWidthMode() == WIDTH_MODE_COMPACT && isHorizontalTabPlacement());
if( isCompact )
title = null;
String clippedTitle = layoutAndClipLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected );
// special title clipping for scroll layout where title of last visible tab on right side may be truncated
if( tabViewport != null && (tabPlacement == TOP || tabPlacement == BOTTOM) ) {
Rectangle viewRect = tabViewport.getViewRect();
viewRect.width -= 4; // subtract width of cropped edge
if( !viewRect.contains( textRect ) ) {
Rectangle r = viewRect.intersection( textRect );
if( r.x > viewRect.x )
clippedTitle = JavaCompatibility.getClippedString( null, metrics, title, r.width );
}
}
// paint title and icon
if( !isCompact )
paintText( g, tabPlacement, font, metrics, tabIndex, clippedTitle, textRect, isSelected );
paintIcon( g, tabPlacement, tabIndex, icon, iconRect, isSelected );
}
@Override @Override
protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics metrics, protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics metrics,
int tabIndex, String title, Rectangle textRect, boolean isSelected ) int tabIndex, String title, Rectangle textRect, boolean isSelected )
@@ -662,20 +803,6 @@ public class FlatTabbedPaneUI
return; return;
} }
// clip title if our layout manager is used
// (normally this is done by invoker, but fails in this case)
if( tabViewport != null &&
(tabPlacement == TOP || tabPlacement == BOTTOM) )
{
Rectangle viewRect = tabViewport.getViewRect();
viewRect.width -= 4; // subtract width of cropped edge
if( !viewRect.contains( textRect ) ) {
Rectangle r = viewRect.intersection( textRect );
if( r.x > viewRect.x )
title = JavaCompatibility.getClippedString( null, metrics, title, r.width );
}
}
// plain text // plain text
Color color; Color color;
if( tabPane.isEnabled() && tabPane.isEnabledAt( tabIndex ) ) { if( tabPane.isEnabled() && tabPane.isEnabledAt( tabIndex ) ) {
@@ -712,17 +839,10 @@ public class FlatTabbedPaneUI
protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex, protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected ) int x, int y, int w, int h, boolean isSelected )
{ {
// paint tab close button
if( isTabClosable( tabIndex ) )
paintTabCloseButton( g, tabIndex, x, y, w, h );
// paint tab separators // paint tab separators
if( clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) && if( clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) &&
!isLastInRun( tabIndex ) ) !isLastInRun( tabIndex ) )
paintTabSeparator( g, tabPlacement, x, y, w, h ); paintTabSeparator( g, tabPlacement, x, y, w, h );
if( isSelected )
paintTabSelection( g, tabPlacement, x, y, w, h );
} }
protected void paintTabCloseButton( Graphics g, int tabIndex, int x, int y, int w, int h ) { protected void paintTabCloseButton( Graphics g, int tabIndex, int x, int y, int w, int h ) {
@@ -755,42 +875,10 @@ public class FlatTabbedPaneUI
} }
protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) { protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
// increase clip bounds in scroll-tab-layout to paint over the separator line
Rectangle clipBounds = isScrollTabLayout() ? g.getClipBounds() : null;
if( clipBounds != null &&
this.contentSeparatorHeight != 0 &&
clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
{
Rectangle newClipBounds = new Rectangle( clipBounds );
int contentSeparatorHeight = scale( this.contentSeparatorHeight );
switch( tabPlacement ) {
case TOP:
default:
newClipBounds.height += contentSeparatorHeight;
break;
case BOTTOM:
newClipBounds.y -= contentSeparatorHeight;
newClipBounds.height += contentSeparatorHeight;
break;
case LEFT:
newClipBounds.width += contentSeparatorHeight;
break;
case RIGHT:
newClipBounds.x -= contentSeparatorHeight;
newClipBounds.width += contentSeparatorHeight;
break;
}
g.setClip( newClipBounds );
}
g.setColor( tabPane.isEnabled() ? underlineColor : disabledUnderlineColor ); g.setColor( tabPane.isEnabled() ? underlineColor : disabledUnderlineColor );
Insets contentInsets = getContentBorderInsets( tabPlacement );
// paint underline selection // paint underline selection
Insets contentInsets = getContentBorderInsets( tabPlacement );
int tabSelectionHeight = scale( this.tabSelectionHeight ); int tabSelectionHeight = scale( this.tabSelectionHeight );
switch( tabPlacement ) { switch( tabPlacement ) {
case TOP: case TOP:
@@ -812,9 +900,6 @@ public class FlatTabbedPaneUI
g.fillRect( x - contentInsets.right, y, tabSelectionHeight, h ); g.fillRect( x - contentInsets.right, y, tabSelectionHeight, h );
break; break;
} }
if( clipBounds != null )
g.setClip( clipBounds );
} }
/** /**
@@ -885,8 +970,15 @@ public class FlatTabbedPaneUI
if( isScrollTabLayout() && selectedIndex >= 0 && tabViewport != null ) { if( isScrollTabLayout() && selectedIndex >= 0 && tabViewport != null ) {
Rectangle tabRect = getTabBounds( tabPane, selectedIndex ); Rectangle tabRect = getTabBounds( tabPane, selectedIndex );
// clip to "scrolling sides" of viewport
// (left and right if horizontal, top and bottom if vertical)
Shape oldClip = g.getClip(); Shape oldClip = g.getClip();
g.setClip( tabViewport.getBounds() ); Rectangle vr = tabViewport.getBounds();
if( isHorizontalTabPlacement() )
g.clipRect( vr.x, 0, vr.width, tabPane.getHeight() );
else
g.clipRect( 0, vr.y, tabPane.getWidth(), vr.height );
paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height ); paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height );
g.setClip( oldClip ); g.setClip( oldClip );
} }
@@ -898,14 +990,46 @@ public class FlatTabbedPaneUI
{ {
} }
@Override protected String layoutAndClipLabel( int tabPlacement, FontMetrics metrics, int tabIndex,
protected void layoutLabel( int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, String title, Icon icon, Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected )
Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected )
{ {
// update textIconGap before used in super class // remove tab insets and space for close button from the tab rectangle
textIconGap = scale( textIconGapUnscaled ); // to get correctly clipped title
tabRect = FlatUIUtils.subtractInsets( tabRect, getTabInsets( tabPlacement, tabIndex ) );
if( isTabClosable( tabIndex ) ) {
tabRect.width -= closeIcon.getIconWidth();
if( !isLeftToRight() )
tabRect.x += closeIcon.getIconWidth();
}
super.layoutLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected ); // icon placement
int iconPlacement = clientPropertyInt( tabPane, TABBED_PANE_TAB_ICON_PLACEMENT, LEADING );
int verticalTextPosition = CENTER;
int horizontalTextPosition = TRAILING;
switch( iconPlacement ) {
case TRAILING: horizontalTextPosition = LEADING; break;
case TOP: verticalTextPosition = BOTTOM; horizontalTextPosition = CENTER; break;
case BOTTOM: verticalTextPosition = TOP; horizontalTextPosition = CENTER; break;
}
// reset rectangles
textRect.setBounds( 0, 0, 0, 0 );
iconRect.setBounds( 0, 0, 0, 0 );
// temporary set "html" client property on tabbed pane, which is used by SwingUtilities.layoutCompoundLabel()
View view = getTextViewForTab( tabIndex );
if( view != null )
tabPane.putClientProperty( "html", view );
// layout label
String clippedTitle = SwingUtilities.layoutCompoundLabel( tabPane, metrics, title, icon,
CENTER, CENTER, verticalTextPosition, horizontalTextPosition,
tabRect, iconRect, textRect, scale( textIconGapUnscaled ) );
// remove temporary client property
tabPane.putClientProperty( "html", null );
return clippedTitle;
} }
@Override @Override
@@ -993,6 +1117,11 @@ public class FlatTabbedPaneUI
return tabPane.getClientProperty( key ); return tabPane.getClientProperty( key );
} }
protected int getTabClientPropertyInt( int tabIndex, String key, int defaultValue ) {
Object value = getTabClientProperty( tabIndex, key );
return (value instanceof Integer) ? (int) value : defaultValue;
}
protected void ensureCurrentLayout() { protected void ensureCurrentLayout() {
// since super.ensureCurrentLayout() is private, // since super.ensureCurrentLayout() is private,
// use super.getTabRunCount() as workaround // use super.getTabRunCount() as workaround
@@ -1028,10 +1157,24 @@ public class FlatTabbedPaneUI
} }
protected int getHiddenTabsNavigation() { protected int getHiddenTabsNavigation() {
String hiddenTabsNavigationStr = (String) tabPane.getClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION ); String str = (String) tabPane.getClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION );
if( hiddenTabsNavigationStr == null ) if( str == null )
hiddenTabsNavigationStr = this.hiddenTabsNavigationStr; str = hiddenTabsNavigationStr;
return parseHiddenTabsNavigation( hiddenTabsNavigationStr ); return parseHiddenTabsNavigation( str );
}
protected int getTabAreaAlignment() {
String str = (String) tabPane.getClientProperty( TABBED_PANE_TAB_AREA_ALIGNMENT );
if( str == null )
str = tabAreaAlignmentStr;
return parseTabAreaAlignment( str );
}
protected int getTabWidthMode() {
String str = (String) tabPane.getClientProperty( TABBED_PANE_TAB_WIDTH_MODE );
if( str == null )
str = tabWidthModeStr;
return parseTabWidthMode( str );
} }
protected static int parseHiddenTabsNavigation( String str ) { protected static int parseHiddenTabsNavigation( String str ) {
@@ -1040,8 +1183,33 @@ public class FlatTabbedPaneUI
switch( str ) { switch( str ) {
default: default:
case "moreTabsButton": return MORE_TABS_BUTTON; case TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON: return MORE_TABS_BUTTON;
case "arrowButtons": return ARROW_BUTTONS; case TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS: return ARROW_BUTTONS;
}
}
protected static int parseTabAreaAlignment( String str ) {
if( str == null )
return ALIGN_LEADING;
switch( str ) {
default:
case TABBED_PANE_TAB_AREA_ALIGN_LEADING: return ALIGN_LEADING;
case TABBED_PANE_TAB_AREA_ALIGN_TRAILING: return ALIGN_TRAILING;
case TABBED_PANE_TAB_AREA_ALIGN_CENTER: return ALIGN_CENTER;
case TABBED_PANE_TAB_AREA_ALIGN_FILL: return ALIGN_FILL;
}
}
protected static int parseTabWidthMode( String str ) {
if( str == null )
return WIDTH_MODE_PREFERRED;
switch( str ) {
default:
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;
} }
} }
@@ -1076,6 +1244,22 @@ public class FlatTabbedPaneUI
((JComponent)tabViewport.getView()).scrollRectToVisible( (Rectangle) rects[selectedIndex].clone() ); ((JComponent)tabViewport.getView()).scrollRectToVisible( (Rectangle) rects[selectedIndex].clone() );
} }
private int getLeadingPreferredWidth() {
return (leadingComponent != null) ? leadingComponent.getPreferredSize().width : 0;
}
private int getLeadingPreferredHeight() {
return (leadingComponent != null) ? leadingComponent.getPreferredSize().height : 0;
}
private int getTrailingPreferredWidth() {
return (trailingComponent != null) ? trailingComponent.getPreferredSize().width : 0;
}
private int getTrailingPreferredHeight() {
return (trailingComponent != null) ? trailingComponent.getPreferredSize().height : 0;
}
private void shiftTabs( int sx, int sy ) { private void shiftTabs( int sx, int sy ) {
if( sx == 0 && sy == 0 ) if( sx == 0 && sy == 0 )
return; return;
@@ -1092,6 +1276,64 @@ public class FlatTabbedPaneUI
} }
} }
private void stretchTabsWidth( int sw, boolean leftToRight ) {
int rsw = sw / rects.length;
int x = rects[0].x - (leftToRight ? 0 : rsw);
for( int i = 0; i < rects.length; i++ ) {
// fix tab component location
Component c = tabPane.getTabComponentAt( i );
if( c != null )
c.setLocation( x + (c.getX() - rects[i].x) + (rsw / 2), c.getY() );
// fix x location and width in rects
rects[i].x = x;
rects[i].width += rsw;
if( leftToRight )
x += rects[i].width;
else if( i + 1 < rects.length )
x = rects[i].x - rects[i+1].width - rsw;
}
// fix width of last tab
int diff = sw - (rsw * rects.length);
rects[rects.length-1].width += diff;
if( !leftToRight )
rects[rects.length-1].x -= diff;
}
private void stretchTabsHeight( int sh ) {
int rsh = sh / rects.length;
int y = rects[0].y;
for( int i = 0; i < rects.length; i++ ) {
// fix tab component location
Component c = tabPane.getTabComponentAt( i );
if( c != null )
c.setLocation( c.getX(), y + (c.getY() - rects[i].y) + (rsh / 2) );
// fix y location and height in rects
rects[i].y = y;
rects[i].height += rsh;
y += rects[i].height;
}
// fix height of last tab
rects[rects.length-1].height += (sh - (rsh * rects.length));
}
private int rectsTotalWidth( boolean leftToRight ) {
int last = rects.length - 1;
return leftToRight
? (rects[last].x + rects[last].width) - rects[0].x
: (rects[0].x + rects[0].width) - rects[last].x;
}
private int rectsTotalHeight() {
int last = rects.length - 1;
return (rects[last].y + rects[last].height) - rects[0].y;
}
//---- class TabCloseButton ----------------------------------------------- //---- class TabCloseButton -----------------------------------------------
private class TabCloseButton private class TabCloseButton
@@ -1718,9 +1960,15 @@ 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_MINIMUM_TAB_WIDTH:
case TABBED_PANE_MAXIMUM_TAB_WIDTH:
case TABBED_PANE_TAB_HEIGHT: case TABBED_PANE_TAB_HEIGHT:
case TABBED_PANE_TAB_INSETS: case TABBED_PANE_TAB_INSETS:
case TABBED_PANE_TAB_AREA_INSETS:
case TABBED_PANE_HIDDEN_TABS_NAVIGATION: case TABBED_PANE_HIDDEN_TABS_NAVIGATION:
case TABBED_PANE_TAB_AREA_ALIGNMENT:
case TABBED_PANE_TAB_WIDTH_MODE:
case TABBED_PANE_TAB_ICON_PLACEMENT:
case TABBED_PANE_TAB_CLOSABLE: case TABBED_PANE_TAB_CLOSABLE:
tabPane.revalidate(); tabPane.revalidate();
tabPane.repaint(); tabPane.repaint();
@@ -1757,6 +2005,8 @@ public class FlatTabbedPaneUI
protected void contentPropertyChange( PropertyChangeEvent e ) { protected void contentPropertyChange( PropertyChangeEvent e ) {
switch( e.getPropertyName() ) { switch( e.getPropertyName() ) {
case TABBED_PANE_MINIMUM_TAB_WIDTH:
case TABBED_PANE_MAXIMUM_TAB_WIDTH:
case TABBED_PANE_TAB_INSETS: case TABBED_PANE_TAB_INSETS:
case TABBED_PANE_TAB_CLOSABLE: case TABBED_PANE_TAB_CLOSABLE:
tabPane.revalidate(); tabPane.revalidate();
@@ -1806,19 +2056,22 @@ public class FlatTabbedPaneUI
Rectangle bounds = tabPane.getBounds(); Rectangle bounds = tabPane.getBounds();
Insets insets = tabPane.getInsets(); Insets insets = tabPane.getInsets();
int tabPlacement = tabPane.getTabPlacement(); int tabPlacement = tabPane.getTabPlacement();
Insets tabAreaInsets = getTabAreaInsets( tabPlacement ); int tabAreaAlignment = getTabAreaAlignment();
Insets tabAreaInsets = getRealTabAreaInsets( tabPlacement );
boolean leftToRight = isLeftToRight(); boolean leftToRight = isLeftToRight();
// layout leading and trailing components in tab area // layout leading and trailing components in tab area
if( tabPlacement == TOP || tabPlacement == BOTTOM ) { if( tabPlacement == TOP || tabPlacement == BOTTOM ) {
// fix x-locations of tabs in right-to-left component orientation // fix x-locations of tabs in right-to-left component orientation
if( !leftToRight ) if( !leftToRight )
shiftTabs( insets.left + tabAreaInsets.right, 0 ); shiftTabs( insets.left + tabAreaInsets.right + getTrailingPreferredWidth(), 0 );
// tab area height (maxTabHeight is zero if tab count is zero) // tab area height (maxTabHeight is zero if tab count is zero)
int tabAreaHeight = (maxTabHeight > 0) int tabAreaHeight = (maxTabHeight > 0)
? maxTabHeight ? maxTabHeight
: Math.max( calculateMaxExtrasHeight(), scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, tabHeight ) ) ); : Math.max(
Math.max( getLeadingPreferredHeight(), getTrailingPreferredHeight() ),
scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, tabHeight ) ) );
// tab area bounds // tab area bounds
int tx = insets.left; int tx = insets.left;
@@ -1828,38 +2081,56 @@ public class FlatTabbedPaneUI
int tw = bounds.width - insets.left - insets.right; int tw = bounds.width - insets.left - insets.right;
int th = tabAreaHeight; int th = tabAreaHeight;
int leadingWidth = getLeadingPreferredWidth();
int trailingWidth = getTrailingPreferredWidth();
// apply tab area alignment
if( runCount == 1 && rects.length > 0 ) {
int availWidth = tw - leadingWidth - trailingWidth - tabAreaInsets.left - tabAreaInsets.right;
int totalTabWidth = rectsTotalWidth( leftToRight );
int diff = availWidth - totalTabWidth;
switch( tabAreaAlignment ) {
case ALIGN_LEADING:
trailingWidth += diff;
break;
case ALIGN_TRAILING:
shiftTabs( leftToRight ? diff : -diff, 0 );
leadingWidth += diff;
break;
case ALIGN_CENTER:
shiftTabs( (leftToRight ? diff : -diff) / 2, 0 );
leadingWidth += diff / 2;
trailingWidth += diff - (diff / 2);
break;
case ALIGN_FILL:
stretchTabsWidth( diff, leftToRight );
break;
}
} else if( rects.length == 0 )
trailingWidth = tw - leadingWidth;
// layout left component // layout left component
Container leftComponent = leftToRight ? leadingComponent : trailingComponent; Container leftComponent = leftToRight ? leadingComponent : trailingComponent;
if( leftComponent != null ) { if( leftComponent != null ) {
// trailing component fills all available horizontal space int leftWidth = leftToRight ? leadingWidth : trailingWidth;
int leftWidth = leftToRight
? leftComponent.getPreferredSize().width
: (rects.length > 0
? rects[rects.length-1].x - tx
- (tabAreaInsets.right - trailingComponent.getPreferredSize().width)
: tw - (leadingComponent != null ? leadingComponent.getPreferredSize().width : 0));
leftComponent.setBounds( tx, ty, leftWidth, th ); leftComponent.setBounds( tx, ty, leftWidth, th );
// reduce tab area bounds
tx += leftWidth;
tw -= leftWidth;
} }
// layout right component // layout right component
Container rightComponent = leftToRight ? trailingComponent : leadingComponent; Container rightComponent = leftToRight ? trailingComponent : leadingComponent;
if( rightComponent != null ) { if( rightComponent != null ) {
// trailing component fills all available horizontal space int rightWidth = leftToRight ? trailingWidth : leadingWidth;
int rightWidth = !leftToRight
? rightComponent.getPreferredSize().width
: (rects.length > 0
? tx + tw - (rects[rects.length-1].x + rects[rects.length-1].width)
- (tabAreaInsets.right - trailingComponent.getPreferredSize().width)
: tw);
rightComponent.setBounds( tx + tw - rightWidth, ty, rightWidth, th ); rightComponent.setBounds( tx + tw - rightWidth, ty, rightWidth, th );
} }
} else { // LEFT and RIGHT tab placement } else { // LEFT and RIGHT tab placement
// tab area width (maxTabWidth is zero if tab count is zero) // tab area width (maxTabWidth is zero if tab count is zero)
int tabAreaWidth = (maxTabWidth > 0) ? maxTabWidth : calculateMaxExtrasWidth(); int tabAreaWidth = (maxTabWidth > 0)
? maxTabWidth
: Math.max( getLeadingPreferredWidth(), getTrailingPreferredWidth() );
// tab area bounds // tab area bounds
int tx = (tabPlacement == LEFT) int tx = (tabPlacement == LEFT)
@@ -1869,25 +2140,45 @@ public class FlatTabbedPaneUI
int tw = tabAreaWidth; int tw = tabAreaWidth;
int th = bounds.height - insets.top - insets.bottom; int th = bounds.height - insets.top - insets.bottom;
int topHeight = getLeadingPreferredHeight();
int bottomHeight = getTrailingPreferredHeight();
// apply tab area alignment
if( runCount == 1 && rects.length > 0 ) {
int availHeight = th - topHeight - bottomHeight - tabAreaInsets.top - tabAreaInsets.bottom;
int totalTabHeight = rectsTotalHeight();
int diff = availHeight - totalTabHeight;
switch( tabAreaAlignment ) {
case ALIGN_LEADING:
bottomHeight += diff;
break;
case ALIGN_TRAILING:
shiftTabs( 0, diff );
topHeight += diff;
break;
case ALIGN_CENTER:
shiftTabs( 0, (diff) / 2 );
topHeight += diff / 2;
bottomHeight += diff - (diff / 2);
break;
case ALIGN_FILL:
stretchTabsHeight( diff );
break;
}
} else if( rects.length == 0 )
bottomHeight = th - topHeight;
// layout top component // layout top component
if( leadingComponent != null ) { if( leadingComponent != null )
int topHeight = leadingComponent.getPreferredSize().height;
leadingComponent.setBounds( tx, ty, tw, topHeight ); leadingComponent.setBounds( tx, ty, tw, topHeight );
// reduce tab area bounds
ty += topHeight;
th -= topHeight;
}
// layout bottom component // layout bottom component
if( trailingComponent != null ) { if( trailingComponent != null )
// trailing component fills all available vertical space
int bottomHeight = (rects.length > 0)
? ty + th - (rects[rects.length-1].y + rects[rects.length-1].height)
- (tabAreaInsets.bottom - trailingComponent.getPreferredSize().height)
: th;
trailingComponent.setBounds( tx, ty + th - bottomHeight, tw, bottomHeight ); trailingComponent.setBounds( tx, ty + th - bottomHeight, tw, bottomHeight );
}
} }
} }
} }
@@ -1968,7 +2259,8 @@ public class FlatTabbedPaneUI
Rectangle bounds = tabPane.getBounds(); Rectangle bounds = tabPane.getBounds();
Insets insets = tabPane.getInsets(); Insets insets = tabPane.getInsets();
int tabPlacement = tabPane.getTabPlacement(); int tabPlacement = tabPane.getTabPlacement();
Insets tabAreaInsets = getTabAreaInsets( tabPlacement ); int tabAreaAlignment = getTabAreaAlignment();
Insets tabAreaInsets = getRealTabAreaInsets( tabPlacement );
Dimension moreButtonSize = useMoreButton ? moreTabsButton.getPreferredSize() : null; Dimension moreButtonSize = useMoreButton ? moreTabsButton.getPreferredSize() : null;
Dimension backwardButtonSize = useMoreButton ? null : backwardButton.getPreferredSize(); Dimension backwardButtonSize = useMoreButton ? null : backwardButton.getPreferredSize();
Dimension forwardButtonSize = useMoreButton ? null : forwardButton.getPreferredSize(); Dimension forwardButtonSize = useMoreButton ? null : forwardButton.getPreferredSize();
@@ -1994,7 +2286,9 @@ public class FlatTabbedPaneUI
// tab area height (maxTabHeight is zero if tab count is zero) // tab area height (maxTabHeight is zero if tab count is zero)
int tabAreaHeight = (maxTabHeight > 0) int tabAreaHeight = (maxTabHeight > 0)
? maxTabHeight ? maxTabHeight
: Math.max( calculateMaxExtrasHeight(), scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, tabHeight ) ) ); : Math.max(
Math.max( getLeadingPreferredHeight(), getTrailingPreferredHeight() ),
scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, tabHeight ) ) );
// tab area bounds // tab area bounds
int tx = insets.left; int tx = insets.left;
@@ -2004,54 +2298,56 @@ public class FlatTabbedPaneUI
int tw = bounds.width - insets.left - insets.right; int tw = bounds.width - insets.left - insets.right;
int th = tabAreaHeight; int th = tabAreaHeight;
int leadingWidth = getLeadingPreferredWidth();
int trailingWidth = getTrailingPreferredWidth();
int availWidth = tw - leadingWidth - trailingWidth - tabAreaInsets.left - tabAreaInsets.right;
int totalTabWidth = (rects.length > 0) ? rectsTotalWidth( leftToRight ) : 0;
// apply tab area alignment
if( totalTabWidth < availWidth && rects.length > 0 ) {
int diff = availWidth - totalTabWidth;
switch( tabAreaAlignment ) {
case ALIGN_LEADING:
trailingWidth += diff;
break;
case ALIGN_TRAILING:
leadingWidth += diff;
break;
case ALIGN_CENTER:
leadingWidth += diff / 2;
trailingWidth += diff - (diff / 2);
break;
case ALIGN_FILL:
stretchTabsWidth( diff, leftToRight );
totalTabWidth = rectsTotalWidth( leftToRight );
break;
}
} else if( rects.length == 0 )
trailingWidth = tw - leadingWidth;
// layout left component // layout left component
Container leftComponent = leftToRight ? leadingComponent : trailingComponent; Container leftComponent = leftToRight ? leadingComponent : trailingComponent;
if( leftComponent != null ) { int leftWidth = leftToRight ? leadingWidth : trailingWidth;
int leftWidth = leftComponent.getPreferredSize().width; if( leftComponent != null )
if( !leftToRight ) {
// trailing component fills all available horizontal space
int leadingWidth = (leadingComponent != null) ? leadingComponent.getPreferredSize().width : 0;
leftWidth = Math.max( leftWidth, (rects.length > 0)
? tw - leadingWidth - (rects[0].x + rects[0].width - rects[rects.length-1].x)
- (tabAreaInsets.left + tabAreaInsets.right)
: tw - leadingWidth );
}
leftComponent.setBounds( tx, ty, leftWidth, th ); leftComponent.setBounds( tx, ty, leftWidth, th );
// reduce tab area bounds
tx += leftWidth;
tw -= leftWidth;
}
// layout right component // layout right component
Container rightComponent = leftToRight ? trailingComponent : leadingComponent; Container rightComponent = leftToRight ? trailingComponent : leadingComponent;
if( rightComponent != null ) { int rightWidth = leftToRight ? trailingWidth : leadingWidth;
int rightWidth = rightComponent.getPreferredSize().width; if( rightComponent != null )
if( leftToRight ) {
// trailing component fills all available horizontal space
rightWidth = Math.max( rightWidth, (rects.length > 0)
? tw - (rects[rects.length-1].x + rects[rects.length-1].width)
- (tabAreaInsets.left + tabAreaInsets.right)
: tw );
}
rightComponent.setBounds( tx + tw - rightWidth, ty, rightWidth, th ); rightComponent.setBounds( tx + tw - rightWidth, ty, rightWidth, th );
// reduce tab area bounds
tw -= rightWidth;
}
// layout tab viewport and buttons // layout tab viewport and buttons
if( rects.length > 0 ) { if( rects.length > 0 ) {
int txi = tx + (leftToRight ? tabAreaInsets.left : tabAreaInsets.right); int txi = tx + leftWidth + (leftToRight ? tabAreaInsets.left : tabAreaInsets.right);
int twi = tw - tabAreaInsets.left - tabAreaInsets.right; int twi = tw - leftWidth - rightWidth - tabAreaInsets.left - tabAreaInsets.right;
// layout viewport and buttons // layout viewport and buttons
int viewportWidth = twi; int viewportWidth = twi;
Rectangle lastRect = rects[rects.length - 1]; if( viewportWidth < totalTabWidth ) {
int tabsWidth = leftToRight
? (lastRect.x + lastRect.width)
: (rects[0].x + rects[0].width - lastRect.x);
if( viewportWidth < tabsWidth ) {
// need buttons // need buttons
buttonsVisible = true; buttonsVisible = true;
int buttonsWidth = useMoreButton ? moreButtonSize.width : (backwardButtonSize.width + forwardButtonSize.width); int buttonsWidth = useMoreButton ? moreButtonSize.width : (backwardButtonSize.width + forwardButtonSize.width);
@@ -2077,7 +2373,9 @@ public class FlatTabbedPaneUI
} }
} else { // LEFT and RIGHT tab placement } else { // LEFT and RIGHT tab placement
// tab area width (maxTabWidth is zero if tab count is zero) // tab area width (maxTabWidth is zero if tab count is zero)
int tabAreaWidth = (maxTabWidth > 0) ? maxTabWidth : calculateMaxExtrasWidth(); int tabAreaWidth = (maxTabWidth > 0)
? maxTabWidth
: Math.max( getLeadingPreferredWidth(), getTrailingPreferredWidth() );
// tab area bounds // tab area bounds
int tx = (tabPlacement == LEFT) int tx = (tabPlacement == LEFT)
@@ -2087,40 +2385,52 @@ public class FlatTabbedPaneUI
int tw = tabAreaWidth; int tw = tabAreaWidth;
int th = bounds.height - insets.top - insets.bottom; int th = bounds.height - insets.top - insets.bottom;
int topHeight = getLeadingPreferredHeight();
int bottomHeight = getTrailingPreferredHeight();
int availHeight = th - topHeight - bottomHeight - tabAreaInsets.top - tabAreaInsets.bottom;
int totalTabHeight = (rects.length > 0) ? rectsTotalHeight() : 0;
// apply tab area alignment
if( totalTabHeight < availHeight && rects.length > 0 ) {
int diff = availHeight - totalTabHeight;
switch( tabAreaAlignment ) {
case ALIGN_LEADING:
bottomHeight += diff;
break;
case ALIGN_TRAILING:
topHeight += diff;
break;
case ALIGN_CENTER:
topHeight += diff / 2;
bottomHeight += diff - (diff / 2);
break;
case ALIGN_FILL:
stretchTabsHeight( diff );
totalTabHeight = rectsTotalHeight();
break;
}
} else if( rects.length == 0 )
bottomHeight = th - topHeight;
// layout top component // layout top component
if( leadingComponent != null ) { if( leadingComponent != null )
int topHeight = leadingComponent.getPreferredSize().height;
leadingComponent.setBounds( tx, ty, tw, topHeight ); leadingComponent.setBounds( tx, ty, tw, topHeight );
// reduce tab area bounds
ty += topHeight;
th -= topHeight;
}
// layout bottom component // layout bottom component
if( trailingComponent != null ) { if( trailingComponent != null )
int bottomHeight = trailingComponent.getPreferredSize().height;
// trailing component fills all available vertical space
bottomHeight = Math.max( bottomHeight, (rects.length > 0)
? th - (rects[rects.length-1].y + rects[rects.length-1].height)
- (tabAreaInsets.top + tabAreaInsets.bottom)
: th );
trailingComponent.setBounds( tx, ty + th - bottomHeight, tw, bottomHeight ); trailingComponent.setBounds( tx, ty + th - bottomHeight, tw, bottomHeight );
// reduce tab area bounds
th -= bottomHeight;
}
// layout tab viewport and buttons // layout tab viewport and buttons
if( rects.length > 0 ) { if( rects.length > 0 ) {
int tyi = ty + tabAreaInsets.top; int tyi = ty + topHeight + tabAreaInsets.top;
int thi = th - tabAreaInsets.top - tabAreaInsets.bottom; int thi = th - topHeight - bottomHeight - tabAreaInsets.top - tabAreaInsets.bottom;
// layout viewport and buttons // layout viewport and buttons
int viewportHeight = thi; int viewportHeight = thi;
Rectangle lastRect = rects[rects.length - 1]; if( viewportHeight < totalTabHeight ) {
int tabsHeight = lastRect.y + lastRect.height;
if( viewportHeight < tabsHeight ) {
// need buttons // need buttons
buttonsVisible = true; buttonsVisible = true;
int buttonsHeight = useMoreButton ? moreButtonSize.height : (backwardButtonSize.height + forwardButtonSize.height); int buttonsHeight = useMoreButton ? moreButtonSize.height : (backwardButtonSize.height + forwardButtonSize.height);

View File

@@ -551,6 +551,7 @@ TabbedPane.disabledForeground=@disabledText
TabbedPane.shadow=@background TabbedPane.shadow=@background
TabbedPane.contentBorderInsets=null TabbedPane.contentBorderInsets=null
TabbedPane.hiddenTabsNavigation=moreTabsButton TabbedPane.hiddenTabsNavigation=moreTabsButton
TabbedPane.tabAreaAlignment=leading
TabbedPane.closeIcon=com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon TabbedPane.closeIcon=com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon
TabbedPane.closeSize=16,16 TabbedPane.closeSize=16,16

View File

@@ -937,6 +937,7 @@ TabbedPane.selectedTabPadInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI
TabbedPane.selectionFollowsFocus true TabbedPane.selectionFollowsFocus true
TabbedPane.shadow #3c3f41 javax.swing.plaf.ColorUIResource [UI] TabbedPane.shadow #3c3f41 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.showTabSeparators false TabbedPane.showTabSeparators false
TabbedPane.tabAreaAlignment leading
TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.tabHeight 32 TabbedPane.tabHeight 32
TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI]

View File

@@ -942,6 +942,7 @@ TabbedPane.selectedTabPadInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI
TabbedPane.selectionFollowsFocus true TabbedPane.selectionFollowsFocus true
TabbedPane.shadow #f2f2f2 javax.swing.plaf.ColorUIResource [UI] TabbedPane.shadow #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.showTabSeparators false TabbedPane.showTabSeparators false
TabbedPane.tabAreaAlignment leading
TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.tabHeight 32 TabbedPane.tabHeight 32
TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI]

View File

@@ -551,7 +551,7 @@ MenuItem.textAcceleratorGap 24
MenuItem.textNoAcceleratorGap 6 MenuItem.textNoAcceleratorGap 6
MenuItem.underlineSelectionBackground #e6e6e6 javax.swing.plaf.ColorUIResource [UI] MenuItem.underlineSelectionBackground #e6e6e6 javax.swing.plaf.ColorUIResource [UI]
MenuItem.underlineSelectionCheckBackground #ccccff javax.swing.plaf.ColorUIResource [UI] MenuItem.underlineSelectionCheckBackground #ccccff javax.swing.plaf.ColorUIResource [UI]
MenuItem.underlineSelectionColor #4a88c7 javax.swing.plaf.ColorUIResource [UI] MenuItem.underlineSelectionColor #ffff00 javax.swing.plaf.ColorUIResource [UI]
MenuItem.underlineSelectionHeight 3 MenuItem.underlineSelectionHeight 3
@@ -909,7 +909,7 @@ TabbedPane.closeIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatTab
TabbedPane.closePressedBackground #00ff00 javax.swing.plaf.ColorUIResource [UI] TabbedPane.closePressedBackground #00ff00 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.closePressedForeground #000000 javax.swing.plaf.ColorUIResource [UI] TabbedPane.closePressedForeground #000000 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.closeSize 16,16 javax.swing.plaf.DimensionUIResource [UI] TabbedPane.closeSize 16,16 javax.swing.plaf.DimensionUIResource [UI]
TabbedPane.contentAreaColor #bbbbbb javax.swing.plaf.ColorUIResource [UI] TabbedPane.contentAreaColor #ff0000 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.contentOpaque true TabbedPane.contentOpaque true
TabbedPane.contentSeparatorHeight 1 TabbedPane.contentSeparatorHeight 1
TabbedPane.darkShadow #696969 javax.swing.plaf.ColorUIResource [UI] TabbedPane.darkShadow #696969 javax.swing.plaf.ColorUIResource [UI]
@@ -932,6 +932,7 @@ TabbedPane.selectedTabPadInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI
TabbedPane.selectionFollowsFocus true TabbedPane.selectionFollowsFocus true
TabbedPane.shadow #ccffcc javax.swing.plaf.ColorUIResource [UI] TabbedPane.shadow #ccffcc javax.swing.plaf.ColorUIResource [UI]
TabbedPane.showTabSeparators false TabbedPane.showTabSeparators false
TabbedPane.tabAreaAlignment leading
TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TabbedPane.tabHeight 32 TabbedPane.tabHeight 32
TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI]
@@ -942,7 +943,7 @@ TabbedPane.tabSeparatorsFullHeight false
TabbedPane.tabsOpaque true TabbedPane.tabsOpaque true
TabbedPane.tabsOverlapBorder false TabbedPane.tabsOverlapBorder false
TabbedPane.textIconGap 4 TabbedPane.textIconGap 4
TabbedPane.underlineColor #4a88c7 javax.swing.plaf.ColorUIResource [UI] TabbedPane.underlineColor #ffff00 javax.swing.plaf.ColorUIResource [UI]
TabbedPaneUI com.formdev.flatlaf.ui.FlatTabbedPaneUI TabbedPaneUI com.formdev.flatlaf.ui.FlatTabbedPaneUI
@@ -1137,7 +1138,7 @@ ToggleButton.tab.disabledUnderlineColor #7a7a7a javax.swing.plaf.ColorUIResou
ToggleButton.tab.focusBackground #dddddd javax.swing.plaf.ColorUIResource [UI] ToggleButton.tab.focusBackground #dddddd javax.swing.plaf.ColorUIResource [UI]
ToggleButton.tab.hoverBackground #eeeeee javax.swing.plaf.ColorUIResource [UI] ToggleButton.tab.hoverBackground #eeeeee javax.swing.plaf.ColorUIResource [UI]
ToggleButton.tab.selectedBackground #00ff00 javax.swing.plaf.ColorUIResource [UI] ToggleButton.tab.selectedBackground #00ff00 javax.swing.plaf.ColorUIResource [UI]
ToggleButton.tab.underlineColor #4a88c7 javax.swing.plaf.ColorUIResource [UI] ToggleButton.tab.underlineColor #ffff00 javax.swing.plaf.ColorUIResource [UI]
ToggleButton.tab.underlineHeight 2 ToggleButton.tab.underlineHeight 2
ToggleButton.textIconGap 4 ToggleButton.textIconGap 4
ToggleButton.textShiftOffset 0 ToggleButton.textShiftOffset 0

View File

@@ -112,6 +112,8 @@ public class FlatContainerTest
} }
customTabsChanged( tabbedPane ); customTabsChanged( tabbedPane );
tabBackForegroundChanged( tabbedPane );
setTabIcons( tabbedPane );
} }
private void addTab( JTabbedPane tabbedPane ) { private void addTab( JTabbedPane tabbedPane ) {
@@ -154,24 +156,44 @@ public class FlatContainerTest
} }
private void tabIconsChanged() { private void tabIconsChanged() {
boolean showTabIcons = tabIconsCheckBox.isSelected(); setTabIcons( tabbedPane1 );
setTabIcons( tabbedPane2 );
setTabIcons( tabbedPane3 );
setTabIcons( tabbedPane4 );
setTabIcons( tabbedPane1, showTabIcons ); tabIconSizeSpinner.setEnabled( tabIconsCheckBox.isSelected() );
setTabIcons( tabbedPane2, showTabIcons );
setTabIcons( tabbedPane3, showTabIcons );
setTabIcons( tabbedPane4, showTabIcons );
tabIconSizeSpinner.setEnabled( showTabIcons );
} }
private void setTabIcons( JTabbedPane tabbedPane, boolean showTabIcons ) { private void setTabIcons( JTabbedPane tabbedPane ) {
boolean showTabIcons = tabIconsCheckBox.isSelected();
Object iconSize = tabIconSizeSpinner.getValue(); Object iconSize = tabIconSizeSpinner.getValue();
Icon icon = showTabIcons Icon icon = null;
? new ScaledImageIcon( new ImageIcon( getClass().getResource( "/com/formdev/flatlaf/testing/test" + iconSize + ".png" ) ) ) Icon disabledIcon = null;
: null; if( showTabIcons ) {
tabbedPane.setIconAt( 0, icon ); ImageIcon imageIcon = new ImageIcon( getClass().getResource( "/com/formdev/flatlaf/testing/test" + iconSize + ".png" ) );
tabbedPane.setIconAt( 1, icon ); icon = new ScaledImageIcon( imageIcon );
disabledIcon = UIManager.getLookAndFeel().getDisabledIcon( tabbedPane, imageIcon );
if( disabledIcon instanceof ImageIcon )
disabledIcon = new ScaledImageIcon( (ImageIcon) disabledIcon );
}
int tabCount = tabbedPane.getTabCount();
for( int i = 0; i < tabCount; i++ ) {
tabbedPane.setIconAt( i, icon );
tabbedPane.setDisabledIconAt( i, disabledIcon );
}
}
private void iconPlacementChanged() {
Object iconPlacement = null;
switch( (String) iconPlacementField.getSelectedItem() ) {
case "leading": iconPlacement = SwingConstants.LEADING; break;
case "trailing": iconPlacement = SwingConstants.TRAILING; break;
case "top": iconPlacement = SwingConstants.TOP; break;
case "bottom": iconPlacement = SwingConstants.BOTTOM; break;
}
putTabbedPanesClientProperty( TABBED_PANE_TAB_ICON_PLACEMENT, iconPlacement );
} }
private void customBorderChanged() { private void customBorderChanged() {
@@ -195,11 +217,11 @@ public class FlatContainerTest
private void customTabsChanged( JTabbedPane tabbedPane ) { private void customTabsChanged( JTabbedPane tabbedPane ) {
boolean customTabs = customTabsCheckBox.isSelected(); boolean customTabs = customTabsCheckBox.isSelected();
int tabCount = tabbedPane.getTabCount(); int tabCount = tabbedPane.getTabCount();
if( tabCount >= 2 ) if( tabCount > 1 )
tabbedPane.setTabComponentAt( 1, customTabs ? new JButton( tabbedPane.getTitleAt( 1 ) ) : null ); tabbedPane.setTabComponentAt( 1, customTabs ? new JButton( tabbedPane.getTitleAt( 1 ) ) : null );
if( tabCount >= 4 ) if( tabCount > 3 )
tabbedPane.setTabComponentAt( 3, customTabs ? createCustomTab( tabbedPane.getTitleAt( 3 ) ) : null ); tabbedPane.setTabComponentAt( 3, customTabs ? createCustomTab( tabbedPane.getTitleAt( 3 ) ) : null );
if( tabCount >= 6 ) if( tabCount > 5 )
tabbedPane.setTabComponentAt( 5, customTabs ? new JCheckBox( tabbedPane.getTitleAt( 5 ) ) : null ); tabbedPane.setTabComponentAt( 5, customTabs ? new JCheckBox( tabbedPane.getTitleAt( 5 ) ) : null );
} }
@@ -219,6 +241,26 @@ public class FlatContainerTest
return tab; return tab;
} }
private void htmlTabsChanged() {
htmlTabsChanged( tabbedPane1 );
htmlTabsChanged( tabbedPane2 );
htmlTabsChanged( tabbedPane3 );
htmlTabsChanged( tabbedPane4 );
}
private void htmlTabsChanged( JTabbedPane tabbedPane ) {
boolean html = htmlTabsCheckBox.isSelected();
boolean multiLine = multiLineTabsCheckBox.isSelected();
String s = multiLine
? "<html><b>Bold</b> Tab<br>Second <i>Line</i> "
: (html ? "<html><b>Bold</b> Tab " : "Tab ");
int tabCount = tabbedPane.getTabCount();
if( tabCount > 0 )
tabbedPane.setTitleAt( 0, s + "1" );
if( tabCount > 3 )
tabbedPane.setTitleAt( 3, s + "4" );
}
private void tabPlacementChanged() { private void tabPlacementChanged() {
int tabPlacement = -1; int tabPlacement = -1;
switch( (String) tabPlacementField.getSelectedItem() ) { switch( (String) tabPlacementField.getSelectedItem() ) {
@@ -235,19 +277,40 @@ public class FlatContainerTest
} }
private void hiddenTabsNavigationChanged() { private void hiddenTabsNavigationChanged() {
String value = null; String value = (String) hiddenTabsNavigationField.getSelectedItem();
switch( (String) hiddenTabsNavigationField.getSelectedItem() ) { if( "default".equals( value ) )
case "moreTabsButton": value = TABBED_PANE_HIDDEN_TABS_NAVIGATION_MORE_TABS_BUTTON; break; value = null;
case "arrowButtons": value = TABBED_PANE_HIDDEN_TABS_NAVIGATION_ARROW_BUTTONS; break;
}
putTabbedPanesClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value ); putTabbedPanesClientProperty( TABBED_PANE_HIDDEN_TABS_NAVIGATION, value );
} }
private void tabAreaAlignmentChanged() {
String value = (String) tabAreaAlignmentField.getSelectedItem();
if( "default".equals( value ) )
value = null;
putTabbedPanesClientProperty( TABBED_PANE_TAB_AREA_ALIGNMENT, value );
}
private void tabWidthModeChanged() {
String value = (String) tabWidthModeField.getSelectedItem();
if( "default".equals( value ) )
value = null;
putTabbedPanesClientProperty( TABBED_PANE_TAB_WIDTH_MODE, value );
}
private void tabBackForegroundChanged() { private void tabBackForegroundChanged() {
tabBackForegroundChanged( tabbedPane1 );
tabBackForegroundChanged( tabbedPane2 );
tabBackForegroundChanged( tabbedPane3 );
tabBackForegroundChanged( tabbedPane4 );
}
private void tabBackForegroundChanged( JTabbedPane tabbedPane ) {
boolean enabled = tabBackForegroundCheckBox.isSelected(); boolean enabled = tabBackForegroundCheckBox.isSelected();
tabbedPane1.setBackgroundAt( 0, enabled ? Color.red : null ); int tabCount = tabbedPane.getTabCount();
tabbedPane1.setForegroundAt( 1, enabled ? Color.red : null ); if( tabCount > 0 )
tabbedPane.setBackgroundAt( 0, enabled ? Color.red : null );
if( tabCount > 1 )
tabbedPane.setForegroundAt( 1, enabled ? Color.red : null );
} }
private void leadingComponentChanged() { private void leadingComponentChanged() {
@@ -293,14 +356,16 @@ public class FlatContainerTest
JTabbedPane[] tabbedPanes = new JTabbedPane[] { tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 }; JTabbedPane[] tabbedPanes = new JTabbedPane[] { tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 };
for( JTabbedPane tabbedPane : tabbedPanes ) { for( JTabbedPane tabbedPane : tabbedPanes ) {
Component c = tabbedPane.getComponentAt( 1 ); if( tabbedPane.getTabCount() > 1 ) {
((JComponent)c).putClientProperty( TABBED_PANE_TAB_CLOSABLE, value ); Component c = tabbedPane.getComponentAt( 1 );
((JComponent)c).putClientProperty( TABBED_PANE_TAB_CLOSABLE, value );
}
} }
} }
private void tabAreaInsetsChanged() { private void tabAreaInsetsChanged() {
UIManager.put( "TabbedPane.tabAreaInsets", tabAreaInsetsCheckBox.isSelected() ? new Insets( 10, 10, 25, 25 ) : null ); Insets insets = tabAreaInsetsCheckBox.isSelected() ? new Insets( 5, 5, 10, 10 ) : null;
FlatLaf.updateUI(); putTabbedPanesClientProperty( TABBED_PANE_TAB_AREA_INSETS, insets );
} }
private void smallerTabHeightChanged() { private void smallerTabHeightChanged() {
@@ -318,11 +383,23 @@ public class FlatContainerTest
JTabbedPane[] tabbedPanes = new JTabbedPane[] { tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 }; JTabbedPane[] tabbedPanes = new JTabbedPane[] { tabbedPane1, tabbedPane2, tabbedPane3, tabbedPane4 };
for( JTabbedPane tabbedPane : tabbedPanes ) { for( JTabbedPane tabbedPane : tabbedPanes ) {
Component c = tabbedPane.getComponentAt( 1 ); if( tabbedPane.getTabCount() > 1 ) {
((JComponent)c).putClientProperty( TABBED_PANE_TAB_INSETS, insets ); Component c = tabbedPane.getComponentAt( 1 );
((JComponent)c).putClientProperty( TABBED_PANE_TAB_INSETS, insets );
}
} }
} }
private void minimumTabWidthChanged() {
Integer minimumTabWidth = minimumTabWidthCheckBox.isSelected() ? 100 : null;
putTabbedPanesClientProperty( TABBED_PANE_MINIMUM_TAB_WIDTH, minimumTabWidth );
}
private void maximumTabWidthChanged() {
Integer maximumTabWidth = maximumTabWidthCheckBox.isSelected() ? 60 : null;
putTabbedPanesClientProperty( TABBED_PANE_MAXIMUM_TAB_WIDTH, maximumTabWidth );
}
private void initComponents() { private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JPanel panel9 = new JPanel(); JPanel panel9 = new JPanel();
@@ -346,6 +423,8 @@ public class FlatContainerTest
JLabel tabCountLabel = new JLabel(); JLabel tabCountLabel = new JLabel();
tabCountSpinner = new JSpinner(); tabCountSpinner = new JSpinner();
customTabsCheckBox = new JCheckBox(); customTabsCheckBox = new JCheckBox();
htmlTabsCheckBox = new JCheckBox();
multiLineTabsCheckBox = new JCheckBox();
JLabel hiddenTabsNavigationLabel = new JLabel(); JLabel hiddenTabsNavigationLabel = new JLabel();
hiddenTabsNavigationField = new JComboBox<>(); hiddenTabsNavigationField = new JComboBox<>();
tabBackForegroundCheckBox = new JCheckBox(); tabBackForegroundCheckBox = new JCheckBox();
@@ -353,6 +432,11 @@ public class FlatContainerTest
tabPlacementField = new JComboBox<>(); tabPlacementField = new JComboBox<>();
tabIconsCheckBox = new JCheckBox(); tabIconsCheckBox = new JCheckBox();
tabIconSizeSpinner = new JSpinner(); tabIconSizeSpinner = new JSpinner();
iconPlacementField = new JComboBox<>();
JLabel tabAreaAlignmentLabel = new JLabel();
tabAreaAlignmentField = new JComboBox<>();
JLabel tabWidthModeLabel = new JLabel();
tabWidthModeField = new JComboBox<>();
tabsClosableCheckBox = new JCheckBox(); tabsClosableCheckBox = new JCheckBox();
customBorderCheckBox = new JCheckBox(); customBorderCheckBox = new JCheckBox();
tabAreaInsetsCheckBox = new JCheckBox(); tabAreaInsetsCheckBox = new JCheckBox();
@@ -365,6 +449,8 @@ public class FlatContainerTest
trailingComponentCheckBox = new JCheckBox(); trailingComponentCheckBox = new JCheckBox();
showTabSeparatorsCheckBox = new JCheckBox(); showTabSeparatorsCheckBox = new JCheckBox();
secondTabWiderCheckBox = new JCheckBox(); secondTabWiderCheckBox = new JCheckBox();
minimumTabWidthCheckBox = new JCheckBox();
maximumTabWidthCheckBox = new JCheckBox();
CellConstraints cc = new CellConstraints(); CellConstraints cc = new CellConstraints();
//======== this ======== //======== this ========
@@ -476,6 +562,9 @@ public class FlatContainerTest
// rows // rows
"[center]" + "[center]" +
"[]" + "[]" +
"[]" +
"[]para" +
"[]" +
"[]para" + "[]para" +
"[]" + "[]" +
"[]para" + "[]para" +
@@ -502,6 +591,16 @@ public class FlatContainerTest
customTabsCheckBox.addActionListener(e -> customTabsChanged()); customTabsCheckBox.addActionListener(e -> customTabsChanged());
tabbedPaneControlPanel.add(customTabsCheckBox, "cell 2 0"); tabbedPaneControlPanel.add(customTabsCheckBox, "cell 2 0");
//---- htmlTabsCheckBox ----
htmlTabsCheckBox.setText("HTML");
htmlTabsCheckBox.addActionListener(e -> htmlTabsChanged());
tabbedPaneControlPanel.add(htmlTabsCheckBox, "cell 2 0");
//---- multiLineTabsCheckBox ----
multiLineTabsCheckBox.setText("multi-line");
multiLineTabsCheckBox.addActionListener(e -> htmlTabsChanged());
tabbedPaneControlPanel.add(multiLineTabsCheckBox, "cell 2 0");
//---- hiddenTabsNavigationLabel ---- //---- hiddenTabsNavigationLabel ----
hiddenTabsNavigationLabel.setText("Hidden tabs navigation:"); hiddenTabsNavigationLabel.setText("Hidden tabs navigation:");
tabbedPaneControlPanel.add(hiddenTabsNavigationLabel, "cell 0 1"); tabbedPaneControlPanel.add(hiddenTabsNavigationLabel, "cell 0 1");
@@ -546,65 +645,114 @@ public class FlatContainerTest
tabIconSizeSpinner.addChangeListener(e -> tabIconsChanged()); tabIconSizeSpinner.addChangeListener(e -> tabIconsChanged());
tabbedPaneControlPanel.add(tabIconSizeSpinner, "cell 2 2"); tabbedPaneControlPanel.add(tabIconSizeSpinner, "cell 2 2");
//---- iconPlacementField ----
iconPlacementField.setModel(new DefaultComboBoxModel<>(new String[] {
"leading",
"trailing",
"top",
"bottom"
}));
iconPlacementField.addActionListener(e -> iconPlacementChanged());
tabbedPaneControlPanel.add(iconPlacementField, "cell 2 2");
//---- tabAreaAlignmentLabel ----
tabAreaAlignmentLabel.setText("Tab area alignment:");
tabbedPaneControlPanel.add(tabAreaAlignmentLabel, "cell 0 3");
//---- tabAreaAlignmentField ----
tabAreaAlignmentField.setModel(new DefaultComboBoxModel<>(new String[] {
"default",
"leading",
"trailing",
"center",
"fill"
}));
tabAreaAlignmentField.addActionListener(e -> tabAreaAlignmentChanged());
tabbedPaneControlPanel.add(tabAreaAlignmentField, "cell 1 3");
//---- tabWidthModeLabel ----
tabWidthModeLabel.setText("Tab width mode:");
tabbedPaneControlPanel.add(tabWidthModeLabel, "cell 2 3");
//---- tabWidthModeField ----
tabWidthModeField.setModel(new DefaultComboBoxModel<>(new String[] {
"default",
"preferred",
"equal",
"compact"
}));
tabWidthModeField.addActionListener(e -> tabWidthModeChanged());
tabbedPaneControlPanel.add(tabWidthModeField, "cell 2 3");
//---- tabsClosableCheckBox ---- //---- tabsClosableCheckBox ----
tabsClosableCheckBox.setText("Tabs closable"); tabsClosableCheckBox.setText("Tabs closable");
tabsClosableCheckBox.addActionListener(e -> tabsClosableChanged()); tabsClosableCheckBox.addActionListener(e -> tabsClosableChanged());
tabbedPaneControlPanel.add(tabsClosableCheckBox, "cell 0 3"); tabbedPaneControlPanel.add(tabsClosableCheckBox, "cell 0 4");
//---- customBorderCheckBox ---- //---- customBorderCheckBox ----
customBorderCheckBox.setText("Custom border"); customBorderCheckBox.setText("Custom border");
customBorderCheckBox.addActionListener(e -> customBorderChanged()); customBorderCheckBox.addActionListener(e -> customBorderChanged());
tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 3"); tabbedPaneControlPanel.add(customBorderCheckBox, "cell 1 4");
//---- tabAreaInsetsCheckBox ---- //---- tabAreaInsetsCheckBox ----
tabAreaInsetsCheckBox.setText("Tab area insets (10,10,25,25)"); tabAreaInsetsCheckBox.setText("Tab area insets (5,5,10,10)");
tabAreaInsetsCheckBox.addActionListener(e -> tabAreaInsetsChanged()); tabAreaInsetsCheckBox.addActionListener(e -> tabAreaInsetsChanged());
tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 3"); tabbedPaneControlPanel.add(tabAreaInsetsCheckBox, "cell 2 4");
//---- secondTabClosableCheckBox ---- //---- secondTabClosableCheckBox ----
secondTabClosableCheckBox.setText("Second Tab closable"); secondTabClosableCheckBox.setText("Second Tab closable");
secondTabClosableCheckBox.addActionListener(e -> secondTabClosableChanged()); secondTabClosableCheckBox.addActionListener(e -> secondTabClosableChanged());
tabbedPaneControlPanel.add(secondTabClosableCheckBox, "cell 0 4"); tabbedPaneControlPanel.add(secondTabClosableCheckBox, "cell 0 5");
//---- hasFullBorderCheckBox ---- //---- hasFullBorderCheckBox ----
hasFullBorderCheckBox.setText("Show content border"); hasFullBorderCheckBox.setText("Show content border");
hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged()); hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged());
tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 4,alignx left,growx 0"); tabbedPaneControlPanel.add(hasFullBorderCheckBox, "cell 1 5,alignx left,growx 0");
//---- smallerTabHeightCheckBox ---- //---- smallerTabHeightCheckBox ----
smallerTabHeightCheckBox.setText("Smaller tab height (26)"); smallerTabHeightCheckBox.setText("Smaller tab height (26)");
smallerTabHeightCheckBox.addActionListener(e -> smallerTabHeightChanged()); smallerTabHeightCheckBox.addActionListener(e -> smallerTabHeightChanged());
tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 4"); tabbedPaneControlPanel.add(smallerTabHeightCheckBox, "cell 2 5");
//---- leadingComponentCheckBox ---- //---- leadingComponentCheckBox ----
leadingComponentCheckBox.setText("Leading component"); leadingComponentCheckBox.setText("Leading component");
leadingComponentCheckBox.addActionListener(e -> leadingComponentChanged()); leadingComponentCheckBox.addActionListener(e -> leadingComponentChanged());
tabbedPaneControlPanel.add(leadingComponentCheckBox, "cell 0 5"); tabbedPaneControlPanel.add(leadingComponentCheckBox, "cell 0 6");
//---- hideContentSeparatorCheckBox ---- //---- hideContentSeparatorCheckBox ----
hideContentSeparatorCheckBox.setText("Hide content separator"); hideContentSeparatorCheckBox.setText("Hide content separator");
hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged()); hideContentSeparatorCheckBox.addActionListener(e -> hideContentSeparatorChanged());
tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 5"); tabbedPaneControlPanel.add(hideContentSeparatorCheckBox, "cell 1 6");
//---- smallerInsetsCheckBox ---- //---- smallerInsetsCheckBox ----
smallerInsetsCheckBox.setText("Smaller tab insets (2,2,2,2)"); smallerInsetsCheckBox.setText("Smaller tab insets (2,2,2,2)");
smallerInsetsCheckBox.addActionListener(e -> smallerInsetsChanged()); smallerInsetsCheckBox.addActionListener(e -> smallerInsetsChanged());
tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 5"); tabbedPaneControlPanel.add(smallerInsetsCheckBox, "cell 2 6");
//---- trailingComponentCheckBox ---- //---- trailingComponentCheckBox ----
trailingComponentCheckBox.setText("Trailing component"); trailingComponentCheckBox.setText("Trailing component");
trailingComponentCheckBox.addActionListener(e -> trailingComponentChanged()); trailingComponentCheckBox.addActionListener(e -> trailingComponentChanged());
tabbedPaneControlPanel.add(trailingComponentCheckBox, "cell 0 6"); tabbedPaneControlPanel.add(trailingComponentCheckBox, "cell 0 7");
//---- showTabSeparatorsCheckBox ---- //---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators"); showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged()); showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 6"); tabbedPaneControlPanel.add(showTabSeparatorsCheckBox, "cell 1 7");
//---- secondTabWiderCheckBox ---- //---- secondTabWiderCheckBox ----
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 6"); tabbedPaneControlPanel.add(secondTabWiderCheckBox, "cell 2 7");
//---- minimumTabWidthCheckBox ----
minimumTabWidthCheckBox.setText("Minimum tab width (100)");
minimumTabWidthCheckBox.addActionListener(e -> minimumTabWidthChanged());
tabbedPaneControlPanel.add(minimumTabWidthCheckBox, "cell 2 8");
//---- maximumTabWidthCheckBox ----
maximumTabWidthCheckBox.setText("Maximum tab width (60)");
maximumTabWidthCheckBox.addActionListener(e -> maximumTabWidthChanged());
tabbedPaneControlPanel.add(maximumTabWidthCheckBox, "cell 2 9");
} }
panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1)); panel9.add(tabbedPaneControlPanel, cc.xywh(1, 11, 3, 1));
} }
@@ -620,11 +768,16 @@ public class FlatContainerTest
private JCheckBox tabScrollCheckBox; private JCheckBox tabScrollCheckBox;
private JSpinner tabCountSpinner; private JSpinner tabCountSpinner;
private JCheckBox customTabsCheckBox; private JCheckBox customTabsCheckBox;
private JCheckBox htmlTabsCheckBox;
private JCheckBox multiLineTabsCheckBox;
private JComboBox<String> hiddenTabsNavigationField; private JComboBox<String> hiddenTabsNavigationField;
private JCheckBox tabBackForegroundCheckBox; private JCheckBox tabBackForegroundCheckBox;
private JComboBox<String> tabPlacementField; private JComboBox<String> tabPlacementField;
private JCheckBox tabIconsCheckBox; private JCheckBox tabIconsCheckBox;
private JSpinner tabIconSizeSpinner; private JSpinner tabIconSizeSpinner;
private JComboBox<String> iconPlacementField;
private JComboBox<String> tabAreaAlignmentField;
private JComboBox<String> tabWidthModeField;
private JCheckBox tabsClosableCheckBox; private JCheckBox tabsClosableCheckBox;
private JCheckBox customBorderCheckBox; private JCheckBox customBorderCheckBox;
private JCheckBox tabAreaInsetsCheckBox; private JCheckBox tabAreaInsetsCheckBox;
@@ -637,6 +790,8 @@ public class FlatContainerTest
private JCheckBox trailingComponentCheckBox; private JCheckBox trailingComponentCheckBox;
private JCheckBox showTabSeparatorsCheckBox; private JCheckBox showTabSeparatorsCheckBox;
private JCheckBox secondTabWiderCheckBox; private JCheckBox secondTabWiderCheckBox;
private JCheckBox minimumTabWidthCheckBox;
private JCheckBox maximumTabWidthCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- class Tab1Panel ---------------------------------------------------- //---- class Tab1Panel ----------------------------------------------------

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[][]para[][]"
} ) { } ) {
name: "tabbedPaneControlPanel" name: "tabbedPaneControlPanel"
"opaque": false "opaque": false
@@ -176,6 +176,26 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0" "value": "cell 2 0"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "htmlTabsCheckBox"
"text": "HTML"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "htmlTabsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "multiLineTabsCheckBox"
"text": "multi-line"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "htmlTabsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "hiddenTabsNavigationLabel" name: "hiddenTabsNavigationLabel"
"text": "Hidden tabs navigation:" "text": "Hidden tabs navigation:"
@@ -261,6 +281,70 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2" "value": "cell 2 2"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "iconPlacementField"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "leading"
addElement( "leading" )
addElement( "trailing" )
addElement( "top" )
addElement( "bottom" )
}
auxiliary() {
"JavaCodeGenerator.variableLocal": false
"JavaCodeGenerator.typeParameters": "String"
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "iconPlacementChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAreaAlignmentLabel"
"text": "Tab area alignment:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "tabAreaAlignmentField"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "default"
addElement( "default" )
addElement( "leading" )
addElement( "trailing" )
addElement( "center" )
addElement( "fill" )
}
auxiliary() {
"JavaCodeGenerator.variableLocal": false
"JavaCodeGenerator.typeParameters": "String"
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabAreaAlignmentChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabWidthModeLabel"
"text": "Tab width mode:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "tabWidthModeField"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "default"
addElement( "default" )
addElement( "preferred" )
addElement( "equal" )
addElement( "compact" )
}
auxiliary() {
"JavaCodeGenerator.variableLocal": false
"JavaCodeGenerator.typeParameters": "String"
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabWidthModeChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "tabsClosableCheckBox" name: "tabsClosableCheckBox"
"text": "Tabs closable" "text": "Tabs closable"
@@ -269,7 +353,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsClosableChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsClosableChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3" "value": "cell 0 4"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "customBorderCheckBox" name: "customBorderCheckBox"
@@ -279,17 +363,17 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customBorderChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customBorderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3" "value": "cell 1 4"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "tabAreaInsetsCheckBox" name: "tabAreaInsetsCheckBox"
"text": "Tab area insets (10,10,25,25)" "text": "Tab area insets (5,5,10,10)"
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabAreaInsetsChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabAreaInsetsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 3" "value": "cell 2 4"
} ) } )
add( new FormComponent( "com.formdev.flatlaf.extras.TriStateCheckBox" ) { add( new FormComponent( "com.formdev.flatlaf.extras.TriStateCheckBox" ) {
name: "secondTabClosableCheckBox" name: "secondTabClosableCheckBox"
@@ -299,7 +383,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "secondTabClosableChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "secondTabClosableChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4" "value": "cell 0 5"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hasFullBorderCheckBox" name: "hasFullBorderCheckBox"
@@ -309,7 +393,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4,alignx left,growx 0" "value": "cell 1 5,alignx left,growx 0"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "smallerTabHeightCheckBox" name: "smallerTabHeightCheckBox"
@@ -319,7 +403,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerTabHeightChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerTabHeightChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 4" "value": "cell 2 5"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingComponentCheckBox" name: "leadingComponentCheckBox"
@@ -329,7 +413,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingComponentChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingComponentChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5" "value": "cell 0 6"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "hideContentSeparatorCheckBox" name: "hideContentSeparatorCheckBox"
@@ -339,7 +423,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideContentSeparatorChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hideContentSeparatorChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5" "value": "cell 1 6"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "smallerInsetsCheckBox" name: "smallerInsetsCheckBox"
@@ -349,7 +433,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerInsetsChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "smallerInsetsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 5" "value": "cell 2 6"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingComponentCheckBox" name: "trailingComponentCheckBox"
@@ -359,7 +443,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingComponentChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingComponentChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6" "value": "cell 0 7"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox" name: "showTabSeparatorsCheckBox"
@@ -369,7 +453,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6" "value": "cell 1 7"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "secondTabWiderCheckBox" name: "secondTabWiderCheckBox"
@@ -379,7 +463,27 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "secondTabWiderChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "secondTabWiderChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 6" "value": "cell 2 7"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "minimumTabWidthCheckBox"
"text": "Minimum tab width (100)"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "minimumTabWidthChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 8"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "maximumTabWidthCheckBox"
"text": "Maximum tab width (60)"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "maximumTabWidthChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 9"
} ) } )
}, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) {
"gridY": 11 "gridY": 11
@@ -390,7 +494,7 @@ new FormModel {
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 810, 745 ) "size": new java.awt.Dimension( 810, 860 )
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3,align center center" "$layoutConstraints": "hidemode 3,align center center"
@@ -420,7 +524,7 @@ new FormModel {
"value": "cell 2 0" "value": "cell 2 0"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 790 ) "location": new java.awt.Point( 0, 890 )
"size": new java.awt.Dimension( 291, 118 ) "size": new java.awt.Dimension( 291, 118 )
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
@@ -445,7 +549,7 @@ new FormModel {
"value": "cell 1 0" "value": "cell 1 0"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 340, 790 ) "location": new java.awt.Point( 340, 890 )
"size": new java.awt.Dimension( 291, 118 ) "size": new java.awt.Dimension( 291, 118 )
} ) } )
} }

View File

@@ -277,12 +277,12 @@ SplitPaneDivider.oneTouchHoverArrowColor=#f00
TabbedPane.disabledForeground=#777 TabbedPane.disabledForeground=#777
TabbedPane.selectedBackground=#0f0 TabbedPane.selectedBackground=#0f0
TabbedPane.selectedForeground=#00f TabbedPane.selectedForeground=#00f
TabbedPane.underlineColor=#4A88C7 TabbedPane.underlineColor=#ff0
TabbedPane.disabledUnderlineColor=#7a7a7a TabbedPane.disabledUnderlineColor=#7a7a7a
TabbedPane.hoverColor=#eee TabbedPane.hoverColor=#eee
TabbedPane.focusColor=#ddd TabbedPane.focusColor=#ddd
TabbedPane.tabSeparatorColor=#00f TabbedPane.tabSeparatorColor=#00f
TabbedPane.contentAreaColor=#bbb TabbedPane.contentAreaColor=#f00
TabbedPane.closeSize=16,16 TabbedPane.closeSize=16,16
TabbedPane.closeArc=999 TabbedPane.closeArc=999

View File

@@ -667,6 +667,7 @@ TabbedPane.selectedTabPadInsets
TabbedPane.selectionFollowsFocus TabbedPane.selectionFollowsFocus
TabbedPane.shadow TabbedPane.shadow
TabbedPane.showTabSeparators TabbedPane.showTabSeparators
TabbedPane.tabAreaAlignment
TabbedPane.tabAreaInsets TabbedPane.tabAreaInsets
TabbedPane.tabHeight TabbedPane.tabHeight
TabbedPane.tabInsets TabbedPane.tabInsets