TabbedPane: support hover and focused tab foreground colors (issue #627)

changed background behavior: `tabbedPane.getBackgroundAt(tabIndex)` now has higher priority than `TabbedPane.focusColor` and `TabbedPane.selectedBackground`
This commit is contained in:
Karl Tauber
2023-01-31 13:58:42 +01:00
parent 1435469ee5
commit 29b801e13d
8 changed files with 76 additions and 22 deletions

View File

@@ -11,6 +11,11 @@ FlatLaf Change Log
- Updated **JetBrains Mono** to
[v2.304](https://github.com/JetBrains/JetBrainsMono/releases/tag/v2.304).
- Theme Editor: Support macOS light and dark themes.
- TabbedPane: Support hover and focused tab foreground colors. (issue #627)
- TabbedPane: `tabbedPane.getBackgroundAt(tabIndex)` now has higher priority
than `TabbedPane.focusColor` and `TabbedPane.selectedBackground`. If
`tabbedPane.setBackgroundAt(tabIndex)` is used to set a color for a single
tab, then this color is now used even if the tab is focused or selected.
- TableHeader: Support column hover and pressed background and foreground
colors. (issue #636)

View File

@@ -128,12 +128,14 @@ import com.formdev.flatlaf.util.UIScale;
*
* @uiDefault TabbedPane.disabledForeground Color
* @uiDefault TabbedPane.selectedBackground Color optional
* @uiDefault TabbedPane.selectedForeground Color
* @uiDefault TabbedPane.selectedForeground Color optional
* @uiDefault TabbedPane.underlineColor Color
* @uiDefault TabbedPane.inactiveUnderlineColor Color
* @uiDefault TabbedPane.disabledUnderlineColor Color
* @uiDefault TabbedPane.hoverColor Color
* @uiDefault TabbedPane.focusColor Color
* @uiDefault TabbedPane.hoverColor Color optional
* @uiDefault TabbedPane.hoverForeground Color optional
* @uiDefault TabbedPane.focusColor Color optional
* @uiDefault TabbedPane.focusForeground Color optional
* @uiDefault TabbedPane.tabSeparatorColor Color optional; defaults to TabbedPane.contentAreaColor
* @uiDefault TabbedPane.contentAreaColor Color
* @uiDefault TabbedPane.minimumTabWidth int optional
@@ -205,7 +207,9 @@ public class FlatTabbedPaneUI
/** @since 2.2 */ @Styleable protected Color inactiveUnderlineColor;
@Styleable protected Color disabledUnderlineColor;
@Styleable protected Color hoverColor;
/** @since 3.1 */ @Styleable protected Color hoverForeground;
@Styleable protected Color focusColor;
/** @since 3.1 */ @Styleable protected Color focusForeground;
@Styleable protected Color tabSeparatorColor;
@Styleable protected Color contentAreaColor;
@@ -328,7 +332,9 @@ public class FlatTabbedPaneUI
inactiveUnderlineColor = FlatUIUtils.getUIColor( "TabbedPane.inactiveUnderlineColor", underlineColor );
disabledUnderlineColor = UIManager.getColor( "TabbedPane.disabledUnderlineColor" );
hoverColor = UIManager.getColor( "TabbedPane.hoverColor" );
hoverForeground = UIManager.getColor( "TabbedPane.hoverForeground" );
focusColor = UIManager.getColor( "TabbedPane.focusColor" );
focusForeground = UIManager.getColor( "TabbedPane.focusForeground" );
tabSeparatorColor = UIManager.getColor( "TabbedPane.tabSeparatorColor" );
contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" );
@@ -397,7 +403,9 @@ public class FlatTabbedPaneUI
inactiveUnderlineColor = null;
disabledUnderlineColor = null;
hoverColor = null;
hoverForeground = null;
focusColor = null;
focusForeground = null;
tabSeparatorColor = null;
contentAreaColor = null;
closeIcon = null;
@@ -1141,22 +1149,37 @@ public class FlatTabbedPaneUI
}
// plain text
Color color;
if( tabPane.isEnabled() && tabPane.isEnabledAt( tabIndex ) ) {
color = tabPane.getForegroundAt( tabIndex );
if( isSelected && selectedForeground != null && color == tabPane.getForeground() )
color = selectedForeground;
} else
color = disabledForeground;
int mnemIndex = FlatLaf.isShowMnemonics() ? tabPane.getDisplayedMnemonicIndexAt( tabIndex ) : -1;
g.setColor( color );
g.setColor( getTabForeground( tabPlacement, tabIndex, isSelected ) );
FlatUIUtils.drawStringUnderlineCharAt( tabPane, g, title, mnemIndex,
textRect.x, textRect.y + metrics.getAscent() );
} );
}
/** @since 3.1 */
protected Color getTabForeground( int tabPlacement, int tabIndex, boolean isSelected ) {
// tabbed pane or tab is disabled
if( !tabPane.isEnabled() || !tabPane.isEnabledAt( tabIndex ) )
return disabledForeground;
// hover
if( hoverForeground != null && getRolloverTab() == tabIndex )
return hoverForeground;
// tab foreground (if set)
Color foreground = tabPane.getForegroundAt( tabIndex );
if( foreground != tabPane.getForeground() )
return foreground;
// focused and selected
if( focusForeground != null && isSelected && FlatUIUtils.isPermanentFocusOwner( tabPane ) )
return focusForeground;
if( selectedForeground != null && isSelected )
return selectedForeground;
return foreground;
}
@Override
protected void paintTabBackground( Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected )
@@ -1169,14 +1192,27 @@ public class FlatTabbedPaneUI
/** @since 2 */
protected Color getTabBackground( int tabPlacement, int tabIndex, boolean isSelected ) {
boolean enabled = tabPane.isEnabled();
return enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex
? hoverColor
: (enabled && isSelected && FlatUIUtils.isPermanentFocusOwner( tabPane )
? focusColor
: (selectedBackground != null && enabled && isSelected
? selectedBackground
: tabPane.getBackgroundAt( tabIndex )));
Color background = tabPane.getBackgroundAt( tabIndex );
// tabbed pane or tab is disabled
if( !tabPane.isEnabled() || !tabPane.isEnabledAt( tabIndex ) )
return background;
// hover
if( hoverColor != null && getRolloverTab() == tabIndex )
return hoverColor;
// tab background (if set)
if( background != tabPane.getBackground() )
return background;
// focused and selected
if( focusColor != null && isSelected && FlatUIUtils.isPermanentFocusOwner( tabPane ) )
return focusColor;
if( selectedBackground != null && isSelected )
return selectedBackground;
return background;
}
@Override
@@ -1431,7 +1467,8 @@ public class FlatTabbedPaneUI
path.append( gap, false );
// fill gap in case that the tab is colored (e.g. focused or hover)
g.setColor( getTabBackground( tabPlacement, selectedIndex, true ) );
Color background = getTabBackground( tabPlacement, selectedIndex, true );
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
((Graphics2D)g).fill( gap );
}
}

View File

@@ -721,7 +721,9 @@ public class TestFlatStyleableInfo
"inactiveUnderlineColor", Color.class,
"disabledUnderlineColor", Color.class,
"hoverColor", Color.class,
"hoverForeground", Color.class,
"focusColor", Color.class,
"focusForeground", Color.class,
"tabSeparatorColor", Color.class,
"contentAreaColor", Color.class,

View File

@@ -727,7 +727,9 @@ public class TestFlatStyleableValue
testColor( c, ui, "inactiveUnderlineColor", 0x123456 );
testColor( c, ui, "disabledUnderlineColor", 0x123456 );
testColor( c, ui, "hoverColor", 0x123456 );
testColor( c, ui, "hoverForeground", 0x123456 );
testColor( c, ui, "focusColor", 0x123456 );
testColor( c, ui, "focusForeground", 0x123456 );
testColor( c, ui, "tabSeparatorColor", 0x123456 );
testColor( c, ui, "contentAreaColor", 0x123456 );

View File

@@ -906,7 +906,9 @@ public class TestFlatStyling
ui.applyStyle( "inactiveUnderlineColor: #fff" );
ui.applyStyle( "disabledUnderlineColor: #fff" );
ui.applyStyle( "hoverColor: #fff" );
ui.applyStyle( "hoverForeground: #fff" );
ui.applyStyle( "focusColor: #fff" );
ui.applyStyle( "focusForeground: #fff" );
ui.applyStyle( "tabSeparatorColor: #fff" );
ui.applyStyle( "contentAreaColor: #fff" );

View File

@@ -1085,12 +1085,14 @@ TabbedPane.disabledForeground #777777 HSL 0 0 47 javax.swing.plaf.Colo
TabbedPane.disabledUnderlineColor #7a7a7a HSL 0 0 48 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.focus #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.focusColor #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.focusForeground #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.font [active] $defaultFont [UI]
TabbedPane.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.hasFullBorder false
TabbedPane.hiddenTabsNavigation moreTabsButton
TabbedPane.highlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.hoverColor #eeeeee HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.hoverForeground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.inactiveUnderlineColor #ff00ff HSL 300 100 50 javax.swing.plaf.ColorUIResource [UI]
TabbedPane.labelShift 1
TabbedPane.light #e3e3e3 HSL 0 0 89 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -377,7 +377,9 @@ TabbedPane.underlineColor = #ff0
TabbedPane.inactiveUnderlineColor = #f0f
TabbedPane.disabledUnderlineColor = #7a7a7a
TabbedPane.hoverColor = #eee
TabbedPane.hoverForeground = #0ff
TabbedPane.focusColor = #ddd
TabbedPane.focusForeground = #ff0
TabbedPane.tabSeparatorColor = #00f
TabbedPane.contentAreaColor = #f00

View File

@@ -848,6 +848,7 @@ TabbedPane.disabledForeground
TabbedPane.disabledUnderlineColor
TabbedPane.focus
TabbedPane.focusColor
TabbedPane.focusForeground
TabbedPane.focusInputMap
TabbedPane.font
TabbedPane.foreground
@@ -855,6 +856,7 @@ TabbedPane.hasFullBorder
TabbedPane.hiddenTabsNavigation
TabbedPane.highlight
TabbedPane.hoverColor
TabbedPane.hoverForeground
TabbedPane.inactiveUnderlineColor
TabbedPane.labelShift
TabbedPane.light