From 77f63e3bdc5c084c388bbaab87c26a028d408449 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 29 Aug 2019 12:12:19 +0200 Subject: [PATCH] FlatArrowButton added (refactored from ComboBox and TabbedPane) --- .../formdev/flatlaf/ui/FlatArrowButton.java | 131 ++++++++++++++++++ .../formdev/flatlaf/ui/FlatComboBoxUI.java | 58 +++----- .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 108 +++------------ 3 files changed, 169 insertions(+), 128 deletions(-) create mode 100644 flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatArrowButton.java diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatArrowButton.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatArrowButton.java new file mode 100644 index 00000000..4e1c1c81 --- /dev/null +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatArrowButton.java @@ -0,0 +1,131 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.ui; + +import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.geom.Path2D; +import javax.swing.plaf.UIResource; +import javax.swing.plaf.basic.BasicArrowButton; + +/** + * Button that draws a scaled arrow in one direction. + * + * @author Karl Tauber + */ +public class FlatArrowButton + extends BasicArrowButton + implements UIResource +{ + private final Color foreground; + private final Color disabledForeground; + private final Color hoverForeground; + private final Color hoverBackground; + + private boolean hover; + + public FlatArrowButton( int direction, Color foreground, Color disabledForeground, + Color hoverForeground, Color hoverBackground ) + { + super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE ); + + this.foreground = foreground; + this.disabledForeground = disabledForeground; + this.hoverForeground = hoverForeground; + this.hoverBackground = hoverBackground; + + setOpaque( false ); + setBorder( null ); + + if( hoverForeground != null || hoverBackground != 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 && hoverBackground != null ) { + g.setColor( hoverBackground ); + 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 + ? (hover && hoverForeground != null ? hoverForeground : foreground) + : disabledForeground ); + g2.fill( arrow ); + } +} diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index ef2d25a7..1df6f805 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -27,7 +27,6 @@ import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; -import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; @@ -36,9 +35,9 @@ import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.ListCellRenderer; +import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; -import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.text.JTextComponent; import com.formdev.flatlaf.util.UIScale; @@ -85,8 +84,6 @@ public class FlatComboBoxUI protected void installDefaults() { super.installDefaults(); - padding = UIScale.scale( padding ); - focusWidth = UIManager.getInt( "Component.focusWidth" ); arc = UIManager.getInt( "Component.arc" ); borderColor = UIManager.getColor( "Component.borderColor" ); @@ -99,6 +96,25 @@ public class FlatComboBoxUI buttonEditableBackground = UIManager.getColor( "ComboBox.buttonEditableBackground" ); buttonArrowColor = UIManager.getColor( "ComboBox.buttonArrowColor" ); buttonDisabledArrowColor = UIManager.getColor( "ComboBox.buttonDisabledArrowColor" ); + + // scale + padding = UIScale.scale( padding ); + } + + @Override + protected void uninstallDefaults() { + super.uninstallDefaults(); + + borderColor = null; + disabledBorderColor = null; + + disabledBackground = null; + disabledForeground = null; + + buttonBackground = null; + buttonEditableBackground = null; + buttonArrowColor = null; + buttonDisabledArrowColor = null; } @Override @@ -184,7 +200,7 @@ public class FlatComboBoxUI @Override protected JButton createArrowButton() { - return new FlatArrowButton(); + return new FlatArrowButton( SwingConstants.SOUTH, buttonArrowColor, buttonDisabledArrowColor, null, null ); } @Override @@ -254,36 +270,4 @@ public class FlatComboBoxUI g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : disabledBackground ); g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height ); } - - //---- class FlatArrowButton ---------------------------------------------- - - private class FlatArrowButton - extends BasicArrowButton - { - FlatArrowButton() { - super( SOUTH, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE ); - - setOpaque( false ); - setBorder( null ); - } - - @Override - public void paint( Graphics g ) { - FlatUIUtils.setRenderingHints( (Graphics2D) g ); - - int w = scale( 9 ); - int h = scale( 5 ); - int x = Math.round( (getWidth() - w) / 2f ); - int y = Math.round( (getHeight() - h) / 2f ); - - Path2D arrow = new Path2D.Float(); - arrow.moveTo( x, y ); - arrow.lineTo( x + w, y ); - arrow.lineTo( x + (w / 2f), y + h ); - arrow.closePath(); - - g.setColor( isEnabled() ? buttonArrowColor : buttonDisabledArrowColor ); - ((Graphics2D)g).fill( arrow ); - } - } } 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 46b48bb1..945fd592 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,16 +18,11 @@ 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; @@ -36,7 +31,6 @@ 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; @@ -116,6 +110,19 @@ public class FlatTabbedPaneUI contentSeparatorHeight = scale( contentSeparatorHeight ); } + @Override + protected void uninstallDefaults() { + super.uninstallDefaults(); + + disabledForeground = null; + selectedForeground = null; + underlineColor = null; + disabledUnderlineColor = null; + hoverColor = null; + focusColor = null; + contentAreaColor = null; + } + @Override protected PropertyChangeListener createPropertyChangeListener() { return new BasicTabbedPaneUI.PropertyChangeHandler() { @@ -133,7 +140,10 @@ public class FlatTabbedPaneUI @Override protected JButton createScrollButton( int direction ) { - return new ScrollableTabButton( direction ); + // this method is invoked before installDefaults(), so we can not use color fields here + return new FlatArrowButton( direction, UIManager.getColor("TabbedPane.shadow"), + UIManager.getColor( "TabbedPane.disabledForeground" ), null, + UIManager.getColor( "TabbedPane.hoverColor" ) ); } @Override @@ -379,88 +389,4 @@ 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 ); - } - } }