From 10e91f9db3cc231944e949ad706db3f61d64bd85 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Wed, 28 Aug 2019 21:51:52 +0200 Subject: [PATCH] TabbedPane: scroll button implemented; do not hover tab if it is disabled --- .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 99 ++++++++++++++++++- .../com/formdev/flatlaf/FlatLaf.properties | 1 + 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java index 7f55a133..9095b356 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java @@ -18,18 +18,25 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.util.UIScale.scale; import java.awt.Color; +import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.geom.Path2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; +import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JTabbedPane; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicTabbedPaneUI; import javax.swing.text.View; import sun.swing.SwingUtilities2; @@ -42,6 +49,7 @@ import sun.swing.SwingUtilities2; * @uiDefault TabbedPane.font Font * @uiDefault TabbedPane.background Color * @uiDefault TabbedPane.foreground Color + * @uiDefault TabbedPane.shadow Color used for scroll arrows and cropped line * @uiDefault TabbedPane.disabledForeground Color * @uiDefault TabbedPane.selectedForeground Color * @uiDefault TabbedPane.underlineColor Color @@ -118,6 +126,11 @@ public class FlatTabbedPaneUI }; } + @Override + protected JButton createScrollButton( int direction ) { + return new ScrollableTabButton( direction ); + } + @Override protected void setRolloverTab( int index ) { int oldIndex = getRolloverTab(); @@ -256,7 +269,7 @@ public class FlatTabbedPaneUI // paint tab background boolean enabled = tabPane.isEnabled(); - g.setColor( enabled && getRolloverTab() == tabIndex + g.setColor( enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex ? hoverColor : (enabled && isSelected && tabPane.hasFocus() ? focusColor @@ -327,4 +340,88 @@ public class FlatTabbedPaneUI private boolean isTopOrBottom( int tabPlacement ) { return tabPlacement == TOP || tabPlacement == BOTTOM; } + + //---- class ScrollableTabButton ------------------------------------------ + + private class ScrollableTabButton + extends BasicArrowButton + implements UIResource + { + private boolean hover; + + public ScrollableTabButton( int direction ) { + super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE ); + + setOpaque( false ); + setBorder( null ); + + addMouseListener( new MouseAdapter() { + @Override + public void mouseEntered( MouseEvent e ) { + hover = true; + repaint(); + } + + @Override + public void mouseExited( MouseEvent e ) { + hover = false; + repaint(); + } + } ); + } + + @Override + public Dimension getPreferredSize() { + return scale( super.getPreferredSize() ); + } + + @Override + public Dimension getMinimumSize() { + return scale( super.getMinimumSize() ); + } + + @Override + public void paint( Graphics g ) { + Graphics2D g2 = (Graphics2D)g; + FlatUIUtils.setRenderingHints( g2 ); + + int width = getWidth(); + int height = getHeight(); + boolean enabled = isEnabled(); + + // paint hover background + if( enabled && hover ) { + g.setColor( hoverColor ); + g.fillRect( 0, 0, width, height ); + } + + int w = scale( 9 ); + int h = scale( 5 ); + int x = Math.round( (width - w) / 2f ); + int y = Math.round( (height - h) / 2f ); + + // arrow for SOUTH direction + Path2D arrow = new Path2D.Float(); + arrow.moveTo( x, y ); + arrow.lineTo( x + w, y ); + arrow.lineTo( x + (w / 2f), y + h ); + arrow.closePath(); + + // rotate arrow if necessary + if( direction == WEST ) { + g2.translate( width, 0 ); + g2.rotate( Math.toRadians( 90 ) ); + } else if( direction == EAST ) { + g2.translate( 0, height ); + g2.rotate( Math.toRadians( 270 ) ); + } else if( direction == NORTH ) { + g2.translate( width, height ); + g2.rotate( Math.toRadians( 180 ) ); + } + + // paint arrow + g.setColor( enabled ? shadow : disabledForeground ); + g2.fill( arrow ); + } + } } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 14cd5081..1d4fd46e 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -135,6 +135,7 @@ TabbedPane.tabAreaInsets=0,0,0,0 TabbedPane.selectedTabPadInsets=0,0,0,0 TabbedPane.tabRunOverlay=0 TabbedPane.tabsOverlapBorder=true +TabbedPane.shadow=@@ComboBox.buttonArrowColor #---- TextArea ----