Icons: cache paths for (complex) immutable icons that may be painted often (e.g. Tree icons or FileView icons)

This commit is contained in:
Karl Tauber
2022-08-11 22:26:48 +02:00
parent fb15cdc546
commit 380dae1017
8 changed files with 102 additions and 55 deletions

View File

@@ -39,6 +39,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatCapsLockIcon
extends FlatAbstractIcon
{
private Path2D path;
public FlatCapsLockIcon() {
super( 16, 16, UIManager.getColor( "PasswordField.capsLockIconColor" ) );
}
@@ -75,11 +77,13 @@ public class FlatCapsLockIcon
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
BasicStroke stroke = new BasicStroke( 1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
path.append( new Area( stroke.createStrokedShape( new Rectangle2D.Float( 5.5f, 11.5f, 5, 2 ) ) ), false );
path.append( new Area( stroke.createStrokedShape( FlatUIUtils.createPath(
2.5,7.5, 8,2, 13.5,7.5, 10.5,7.5, 10.5,9.5, 5.5,9.5, 5.5,7.5, 2.5,7.5 ) ) ), false );
if( path == null ) {
path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
path.append( new Area( stroke.createStrokedShape( new Rectangle2D.Float( 5.5f, 11.5f, 5, 2 ) ) ), false );
path.append( new Area( stroke.createStrokedShape( FlatUIUtils.createPath(
2.5,7.5, 8,2, 13.5,7.5, 10.5,7.5, 10.5,9.5, 5.5,9.5, 5.5,7.5, 2.5,7.5 ) ) ), false );
}
g.fill( path );
}
}

View File

@@ -33,6 +33,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatFileViewDirectoryIcon
extends FlatAbstractIcon
{
private Path2D path;
public FlatFileViewDirectoryIcon() {
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
}
@@ -47,7 +49,9 @@ public class FlatFileViewDirectoryIcon
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
g.draw( createFolderPath() );
if( path == null )
path = createFolderPath();
g.draw( path );
}
static Path2D createFolderPath() {

View File

@@ -20,6 +20,7 @@ import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
@@ -33,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatFileViewFileIcon
extends FlatAbstractIcon
{
private Path2D path;
public FlatFileViewFileIcon() {
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
}
@@ -51,19 +54,23 @@ public class FlatFileViewFileIcon
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
double arc = 1.5;
g.draw( FlatUIUtils.createPath(
// top-left
2.5,1.5+arc, FlatUIUtils.QUAD_TO, 2.5,1.5, 2.5+arc,1.5,
// top-right
8.8,1.5, 13.5,6.2,
// bottom-right
13.5,14.5-arc, FlatUIUtils.QUAD_TO, 13.5,14.5, 13.5-arc,14.5,
// bottom-left
2.5+arc,14.5, FlatUIUtils.QUAD_TO, 2.5,14.5, 2.5,14.5-arc ) );
if( path == null ) {
double arc = 1.5;
path = FlatUIUtils.createPath( false,
// top-left
2.5,1.5+arc, FlatUIUtils.QUAD_TO, 2.5,1.5, 2.5+arc,1.5,
// top-right
8.8,1.5, 13.5,6.2,
// bottom-right
13.5,14.5-arc, FlatUIUtils.QUAD_TO, 13.5,14.5, 13.5-arc,14.5,
// bottom-left
2.5+arc,14.5, FlatUIUtils.QUAD_TO, 2.5,14.5, 2.5,14.5-arc,
FlatUIUtils.CLOSE_PATH,
g.draw( FlatUIUtils.createPath( false, 8.5,2,
8.5,6.5-arc, FlatUIUtils.QUAD_TO, 8.5,6.5, 8.5+arc,6.5,
13,6.5 ) );
FlatUIUtils.MOVE_TO, 8.5,2,
8.5,6.5-arc, FlatUIUtils.QUAD_TO, 8.5,6.5, 8.5+arc,6.5,
13,6.5 );
}
g.draw( path );
}
}

View File

@@ -46,6 +46,7 @@ public class FlatSearchIcon
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
private final boolean ignoreButtonState;
private Area area;
public FlatSearchIcon() {
this( false );
@@ -89,9 +90,11 @@ public class FlatSearchIcon
null, searchIconHoverColor, searchIconPressedColor ) );
// paint magnifier
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
if( area == null ) {
area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
}
g.fill( area );
}
}

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.icons;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.UIManager;
/**
@@ -31,6 +32,8 @@ import javax.swing.UIManager;
public class FlatTreeClosedIcon
extends FlatAbstractIcon
{
private Path2D path;
public FlatTreeClosedIcon() {
super( 16, 16, UIManager.getColor( "Tree.icon.closedColor" ) );
}
@@ -47,6 +50,8 @@ public class FlatTreeClosedIcon
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
g.draw( FlatFileViewDirectoryIcon.createFolderPath() );
if( path == null )
path = FlatFileViewDirectoryIcon.createFolderPath();
g.draw( path );
}
}

View File

@@ -41,6 +41,7 @@ public class FlatTreeCollapsedIcon
extends FlatAbstractIcon
{
private final boolean chevron;
private Path2D path;
public FlatTreeCollapsedIcon() {
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
@@ -62,10 +63,14 @@ public class FlatTreeCollapsedIcon
if( chevron ) {
// chevron arrow
g.setStroke( new BasicStroke( 1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER ) );
g.draw( FlatUIUtils.createPath( false, 3.5,1.5, 7.5,5.5, 3.5,9.5 ) );
if( path == null )
path = FlatUIUtils.createPath( false, 3.5,1.5, 7.5,5.5, 3.5,9.5 );
g.draw( path );
} else {
// triangle arrow
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
if( path == null )
path = FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 );
g.fill( path );
}
}

View File

@@ -20,6 +20,7 @@ import java.awt.BasicStroke;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
@@ -33,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
public class FlatTreeOpenIcon
extends FlatAbstractIcon
{
private Path2D path;
public FlatTreeOpenIcon() {
super( 16, 16, UIManager.getColor( "Tree.icon.openColor" ) );
}
@@ -50,28 +53,31 @@ public class FlatTreeOpenIcon
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ) );
double arc = 1.5;
double arc2 = 0.5;
g.draw( FlatUIUtils.createPath( false,
// bottom-left of opend part
2,13.5,
// top-left of opend part
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
// top-right of opend part
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
if( path == null ) {
double arc = 1.5;
double arc2 = 0.5;
path = FlatUIUtils.createPath( false,
// bottom-left of opend part
2,13.5,
// top-left of opend part
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
// top-right of opend part
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
// bottom-right
FlatUIUtils.ROUNDED, 13,13.5, arc,
// bottom-left
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
// top-left
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
// top-mid-left
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
// top-mid-right
8.5,4.5,
// top-right
13.5-arc,4.5, FlatUIUtils.QUAD_TO, 13.5,4.5, 13.5,4.5+arc,
13.5,6.5 ) );
// bottom-right
FlatUIUtils.ROUNDED, 13,13.5, arc,
// bottom-left
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
// top-left
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
// top-mid-left
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
// top-mid-right
8.5,4.5,
// top-right
13.5-arc,4.5, FlatUIUtils.QUAD_TO, 13.5,4.5, 13.5,4.5+arc,
13.5,6.5 );
}
g.draw( path );
}
}

View File

@@ -896,9 +896,11 @@ debug*/
}
debug*/
/** @since 3 */ public static final double QUAD_TO = Double.MIN_VALUE;
/** @since 3 */ public static final double CURVE_TO = Double.MIN_NORMAL;
/** @since 3 */ public static final double ROUNDED = Double.MAX_VALUE;
/** @since 3 */ public static final double MOVE_TO = -1_000_000_000_001.;
/** @since 3 */ public static final double QUAD_TO = -1_000_000_000_002.;
/** @since 3 */ public static final double CURVE_TO = -1_000_000_000_003.;
/** @since 3 */ public static final double ROUNDED = -1_000_000_000_004.;
/** @since 3 */ public static final double CLOSE_PATH = -1_000_000_000_005.;
/**
* Creates a closed path for the given points.
@@ -914,17 +916,23 @@ debug*/
Path2D path = new Path2D.Float( Path2D.WIND_NON_ZERO, points.length / 2 + (close ? 1 : 0) );
path.moveTo( points[0], points[1] );
for( int i = 2; i < points.length; ) {
if( points[i] == QUAD_TO ) {
double p = points[i];
if( p == MOVE_TO ) {
// move pointer to
// params: x, y
path.moveTo( points[i + 1], points[i + 2] );
i += 3;
} else if( p == QUAD_TO ) {
// add quadratic curve
// params: x1, y1, x2, y2
path.quadTo( points[i + 1], points[i + 2], points[i + 3], points[i + 4] );
i += 5;
} else if( points[i] == CURVE_TO ) {
} else if( p == CURVE_TO ) {
// add bezier curve
// params: x1, y1, x2, y2, x3, y3
path.curveTo( points[i + 1], points[i + 2], points[i + 3], points[i + 4], points[i + 5], points[i + 6] );
i += 7;
} else if( points[i] == ROUNDED ) {
} else if( p == ROUNDED ) {
// add rounded corner
// params: x, y, arc
double x = points[i + 1];
@@ -952,10 +960,15 @@ debug*/
path.quadTo( x, y, lerp( x, x2, t2 ), lerp( y, y2, t2 ) );
i += 4;
} else if( p == CLOSE_PATH ) {
// close path
// params: -
path.closePath();
i += 1;
} else {
// add line
// add line to
// params: x, y
path.lineTo( points[i], points[i + 1] );
path.lineTo( p, points[i + 1] );
i += 2;
}
}