FlatArrowButton added (refactored from ComboBox and TabbedPane)

This commit is contained in:
Karl Tauber
2019-08-29 12:12:19 +02:00
parent a28713dce6
commit 77f63e3bdc
3 changed files with 169 additions and 128 deletions

View File

@@ -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 );
}
}

View File

@@ -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 );
}
}
}

View File

@@ -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 );
}
}
}