chevron arrows implemented (closes #7)

use chevron arrows in "Flat Light" and "Flat Dark" themes, but keep triangle arrows in "Flat IntelliJ" and "Flat Darcula" themes
This commit is contained in:
Karl Tauber
2019-10-02 19:13:47 +02:00
parent 8ea23fc533
commit 144f79f0f9
13 changed files with 86 additions and 24 deletions

View File

@@ -3,6 +3,8 @@ FlatLaf Change Log
## Unreleased
- Use new chevron arrows in "Flat Light" and "Flat Dark" themes, but keep
triangle arrows in "Flat IntelliJ" and "Flat Darcula" themes. (issue #7)
- Added Java 9 module descriptor `module-info.class` to `flatlaf.jar` (in
`META-INF/versions/9`). But FlatLaf remains Java 8 compatible. (issue #1)

View File

@@ -16,9 +16,11 @@
package com.formdev.flatlaf.icons;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Path2D;
import javax.swing.JMenu;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
@@ -26,6 +28,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "arrow" icon for {@link javax.swing.JMenu}.
*
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Menu.icon.arrowColor Color
* @uiDefault Menu.icon.disabledArrowColor Color
* @uiDefault Menu.selectionForeground Color
@@ -35,12 +38,13 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatMenuArrowIcon
extends FlatAbstractIcon
{
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
protected final Color arrowColor = UIManager.getColor( "Menu.icon.arrowColor" );
protected final Color disabledArrowColor = UIManager.getColor( "Menu.icon.disabledArrowColor" );
protected final Color selectionForeground = UIManager.getColor( "Menu.selectionForeground" );
public FlatMenuArrowIcon() {
super( 5, 10, null );
super( 6, 10, null );
}
@Override
@@ -49,7 +53,15 @@ public class FlatMenuArrowIcon
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
g.setColor( getArrowColor( c ) );
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
if( chevron ) {
// chevron arrow
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 1,9 );
g.setStroke( new BasicStroke( 1f ) );
g.draw( path );
} else {
// triangle arrow
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
}
}
private Color getArrowColor( Component c ) {

View File

@@ -16,6 +16,7 @@
package com.formdev.flatlaf.icons;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import javax.swing.UIManager;
@@ -24,6 +25,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "collapsed" icon for {@link javax.swing.JTree}.
*
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Tree.icon.collapsedColor Color
*
* @author Karl Tauber
@@ -31,15 +33,32 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatTreeCollapsedIcon
extends FlatAbstractIcon
{
private final boolean chevron;
public FlatTreeCollapsedIcon() {
super( 11, 11, UIManager.getColor( "Tree.icon.collapsedColor" ) );
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
}
FlatTreeCollapsedIcon( Color color ) {
super( 11, 11, color );
chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
rotate( c, g );
if( chevron ) {
// chevron arrow
g.fill( FlatUIUtils.createPath( 3,1, 3,2.5, 6,5.5, 3,8.5, 3,10, 4.5,10, 9,5.5, 4.5,1 ) );
} else {
// triangle arrow
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
}
}
void rotate( Component c, Graphics2D g ) {
if( !c.getComponentOrientation().isLeftToRight() )
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
}
}

View File

@@ -19,7 +19,6 @@ package com.formdev.flatlaf.icons;
import java.awt.Component;
import java.awt.Graphics2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "expanded" icon for {@link javax.swing.JTree}.
@@ -29,14 +28,14 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
* @author Karl Tauber
*/
public class FlatTreeExpandedIcon
extends FlatAbstractIcon
extends FlatTreeCollapsedIcon
{
public FlatTreeExpandedIcon() {
super( 11, 11, UIManager.getColor( "Tree.icon.expandedColor" ) );
super( UIManager.getColor( "Tree.icon.expandedColor" ) );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
g.fill( FlatUIUtils.createPath( 1,2, 10,2, 5.5,10 ) );
void rotate( Component c, Graphics2D g ) {
g.rotate( Math.toRadians( 90 ), width / 2., height / 2. );
}
}

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
@@ -37,6 +38,7 @@ public class FlatArrowButton
extends BasicArrowButton
implements UIResource
{
private final boolean chevron;
private final Color foreground;
private final Color disabledForeground;
private final Color hoverForeground;
@@ -47,11 +49,12 @@ public class FlatArrowButton
private boolean hover;
public FlatArrowButton( int direction, Color foreground, Color disabledForeground,
public FlatArrowButton( int direction, String type, Color foreground, Color disabledForeground,
Color hoverForeground, Color hoverBackground )
{
super( direction, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE );
this.chevron = "chevron".equals( type );
this.foreground = foreground;
this.disabledForeground = disabledForeground;
this.hoverForeground = hoverForeground;
@@ -121,8 +124,8 @@ public class FlatArrowButton
int direction = getDirection();
boolean vert = (direction == NORTH || direction == SOUTH);
int w = scale( 9 );
int h = scale( 5 );
int w = scale( chevron ? 8 : 9 );
int h = scale( chevron ? 4 : 5 );
int x = Math.round( (width - (vert ? w : h)) / 2f + scale( (float) xOffset ) );
int y = Math.round( (height - (vert ? h : w)) / 2f + scale( (float) yOffset ) );
@@ -131,16 +134,23 @@ public class FlatArrowButton
? (hover && hoverForeground != null ? hoverForeground : foreground)
: disabledForeground );
g.translate( x, y );
g2.fill( createArrowShape( direction, w, h ) );
Shape arrowShape = createArrowShape( direction, chevron, w, h );
if( chevron ) {
g2.setStroke( new BasicStroke( scale( 1f ) ) );
g2.draw( arrowShape );
} else {
// triangle
g2.fill( arrowShape );
}
g.translate( -x, -y );
}
public static Shape createArrowShape( int direction, int w, int h ) {
public static Shape createArrowShape( int direction, boolean chevron, int w, int h ) {
switch( direction ) {
case NORTH: return FlatUIUtils.createPath( 0,h, w,h, (w / 2f),0 );
case SOUTH: return FlatUIUtils.createPath( 0,0, w,0, (w / 2f),h );
case WEST: return FlatUIUtils.createPath( h,0, h,w, 0,(w / 2f) );
case EAST: return FlatUIUtils.createPath( 0,0, 0,w, h,(w / 2f) );
case NORTH: return FlatUIUtils.createPath( !chevron, 0,h, (w / 2f),0, w,h );
case SOUTH: return FlatUIUtils.createPath( !chevron, 0,0, (w / 2f),h, w,0 );
case WEST: return FlatUIUtils.createPath( !chevron, h,0, 0,(w / 2f), h,w );
case EAST: return FlatUIUtils.createPath( !chevron, 0,0, h,(w / 2f), 0,w );
default: return new Path2D.Float();
}
}

View File

@@ -57,6 +57,7 @@ import com.formdev.flatlaf.util.UIScale;
*
* @uiDefault Component.focusWidth int
* @uiDefault Component.arc int
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Component.borderColor Color
* @uiDefault Component.disabledBorderColor Color
* @uiDefault ComboBox.disabledBackground Color
@@ -74,6 +75,7 @@ public class FlatComboBoxUI
{
protected int focusWidth;
protected int arc;
protected String arrowType;
protected Color borderColor;
protected Color disabledBorderColor;
@@ -96,6 +98,7 @@ public class FlatComboBoxUI
focusWidth = UIManager.getInt( "Component.focusWidth" );
arc = UIManager.getInt( "Component.arc" );
arrowType = UIManager.getString( "Component.arrowType" );
borderColor = UIManager.getColor( "Component.borderColor" );
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
@@ -224,7 +227,7 @@ public class FlatComboBoxUI
@Override
protected JButton createArrowButton() {
return new FlatArrowButton( SwingConstants.SOUTH, buttonArrowColor,
return new FlatArrowButton( SwingConstants.SOUTH, arrowType, buttonArrowColor,
buttonDisabledArrowColor, buttonHoverArrowColor, null );
}

View File

@@ -48,6 +48,7 @@ import javax.swing.plaf.basic.BasicSpinnerUI;
* @uiDefault Component.focusWidth int
* @uiDefault Component.arc int
* @uiDefault Component.minimumWidth int
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault Component.borderColor Color
* @uiDefault Component.disabledBorderColor Color
* @uiDefault Spinner.disabledBackground Color
@@ -68,6 +69,7 @@ public class FlatSpinnerUI
protected int focusWidth;
protected int arc;
protected int minimumWidth;
protected String arrowType;
protected Color borderColor;
protected Color disabledBorderColor;
protected Color disabledBackground;
@@ -89,6 +91,7 @@ public class FlatSpinnerUI
focusWidth = UIManager.getInt( "Component.focusWidth" );
arc = UIManager.getInt( "Component.arc" );
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
arrowType = UIManager.getString( "Component.arrowType" );
borderColor = UIManager.getColor( "Component.borderColor" );
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
@@ -209,7 +212,7 @@ public class FlatSpinnerUI
}
private Component createArrowButton( int direction, String name ) {
FlatArrowButton button = new FlatArrowButton( direction, buttonArrowColor,
FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor,
buttonDisabledArrowColor, buttonHoverArrowColor, null );
button.setName( name );
button.setYOffset( (direction == SwingConstants.NORTH) ? 1 : -1 );

View File

@@ -31,6 +31,7 @@ import com.formdev.flatlaf.util.UIScale;
/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JSplitPane}.
*
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault SplitPane.background Color
* @uiDefault SplitPane.foreground Color unused
* @uiDefault SplitPane.dividerSize int
@@ -46,6 +47,7 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatSplitPaneUI
extends BasicSplitPaneUI
{
protected String arrowType;
private Boolean continuousLayout;
private Color oneTouchArrowColor;
private Color oneTouchHoverArrowColor;
@@ -56,6 +58,8 @@ public class FlatSplitPaneUI
@Override
protected void installDefaults() {
arrowType = UIManager.getString( "Component.arrowType" );
// get one-touch colors before invoking super.installDefaults() because they are
// used in there on LaF switching
oneTouchArrowColor = UIManager.getColor( "SplitPaneDivider.oneTouchArrowColor" );
@@ -108,7 +112,7 @@ public class FlatSplitPaneUI
private final boolean left;
public FlatOneTouchButton( boolean left ) {
super( SwingConstants.NORTH, oneTouchArrowColor, null, oneTouchHoverArrowColor, null );
super( SwingConstants.NORTH, arrowType, oneTouchArrowColor, null, oneTouchHoverArrowColor, null );
setCursor( Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR ) );
this.left = left;

View File

@@ -39,6 +39,7 @@ import javax.swing.text.View;
*
* @clientProperty JTabbedPane.hasFullBorder boolean
*
* @uiDefault Component.arrowType String triangle (default) or chevron
* @uiDefault TabbedPane.font Font
* @uiDefault TabbedPane.background Color
* @uiDefault TabbedPane.foreground Color
@@ -144,7 +145,8 @@ public class FlatTabbedPaneUI
@Override
protected JButton createScrollButton( int direction ) {
// this method is invoked before installDefaults(), so we can not use color fields here
return new FlatArrowButton( direction, UIManager.getColor("TabbedPane.shadow"),
return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ),
UIManager.getColor( "TabbedPane.shadow" ),
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
UIManager.getColor( "TabbedPane.hoverColor" ) );
}

View File

@@ -181,11 +181,16 @@ public class FlatUIUtils
}
public static Path2D createPath( double... points ) {
return createPath( true, points );
}
public static Path2D createPath( boolean close, double... points ) {
Path2D path = new Path2D.Float();
path.moveTo( points[0], points[1] );
for( int i = 2; i < points.length; i += 2 )
path.lineTo( points[i], points[i + 1] );
path.closePath();
if( close )
path.closePath();
return path;
}

View File

@@ -21,6 +21,7 @@
#---- Component ----
Component.focusWidth=2
Component.arrowType=triangle
#---- RadioButton ----

View File

@@ -37,6 +37,7 @@ CheckBox.icon.selectedPressedBackground=72A1D4
#---- Component ----
Component.focusWidth=2
Component.arrowType=triangle
#---- RadioButton ----

View File

@@ -105,6 +105,7 @@ ComboBox.padding=2,6,2,6
Component.focusWidth=0
Component.arc=5
Component.minimumWidth=64
Component.arrowType=chevron
#---- EditorPane ----