mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
Panel: support painting background with rounded corners (issue #367)
FlatLineBorder: support rounded corners
This commit is contained in:
@@ -64,6 +64,7 @@ FlatLaf Change Log
|
||||
- MenuItem:
|
||||
- Paint the selected icon when the item is selected. (PR #415)
|
||||
- Vertically align text if icons have different widths. (issue #437)
|
||||
- Panel: Support painting background with rounded corners. (issue #367)
|
||||
- Added more color functions to class `ColorFunctions` for easy use in
|
||||
applications: `lighten()`, `darken()`, `saturate()`, `desaturate()`, `spin()`,
|
||||
`tint()`, `shade()` and `luma()`.
|
||||
|
||||
@@ -582,17 +582,18 @@ class UIDefaultsLoader
|
||||
|
||||
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||
if( value.indexOf( ',' ) >= 0 ) {
|
||||
// top,left,bottom,right[,lineColor[,lineThickness]]
|
||||
// top,left,bottom,right[,lineColor[,lineThickness[,arc]]]
|
||||
List<String> parts = splitFunctionParams( value, ',' );
|
||||
Insets insets = parseInsets( value );
|
||||
ColorUIResource lineColor = (parts.size() >= 5)
|
||||
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
|
||||
: null;
|
||||
float lineThickness = (parts.size() >= 6) ? parseFloat( parts.get( 5 ), true ) : 1f;
|
||||
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ), true ) : 1f;
|
||||
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ), true ) : 0;
|
||||
|
||||
return (LazyValue) t -> {
|
||||
return (lineColor != null)
|
||||
? new FlatLineBorder( insets, lineColor, lineThickness )
|
||||
? new FlatLineBorder( insets, lineColor, lineThickness, arc )
|
||||
: new FlatEmptyBorder( insets );
|
||||
};
|
||||
} else
|
||||
|
||||
@@ -37,15 +37,18 @@ public class FlatLineBorder
|
||||
{
|
||||
private final Color lineColor;
|
||||
private final float lineThickness;
|
||||
/** @since 2 */ private final int arc;
|
||||
|
||||
public FlatLineBorder( Insets insets, Color lineColor ) {
|
||||
this( insets, lineColor, 1f );
|
||||
this( insets, lineColor, 1f, 0 );
|
||||
}
|
||||
|
||||
public FlatLineBorder( Insets insets, Color lineColor, float lineThickness ) {
|
||||
/** @since 2 */
|
||||
public FlatLineBorder( Insets insets, Color lineColor, float lineThickness, int arc ) {
|
||||
super( insets );
|
||||
this.lineColor = lineColor;
|
||||
this.lineThickness = lineThickness;
|
||||
this.arc = arc;
|
||||
}
|
||||
|
||||
public Color getLineColor() {
|
||||
@@ -56,13 +59,18 @@ public class FlatLineBorder
|
||||
return lineThickness;
|
||||
}
|
||||
|
||||
/** @since 2 */
|
||||
public int getArc() {
|
||||
return arc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
FlatUIUtils.setRenderingHints( g2 );
|
||||
FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height,
|
||||
0, 0, 0, scale( getLineThickness() ), 0, null, getLineColor(), null );
|
||||
0, 0, 0, scale( getLineThickness() ), scale( getArc() ), null, getLineColor(), null );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
|
||||
@@ -16,14 +16,18 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Map;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicPanelUI;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPanel}.
|
||||
@@ -32,7 +36,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
*
|
||||
* @uiDefault Panel.font Font unused
|
||||
* @uiDefault Panel.background Color only used if opaque
|
||||
* @uiDefault Panel.foreground Color
|
||||
* @uiDefault Panel.foreground Color unused
|
||||
* @uiDefault Panel.border Border
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -41,6 +45,9 @@ public class FlatPanelUI
|
||||
extends BasicPanelUI
|
||||
implements StyleableUI
|
||||
{
|
||||
// only used via styling (not in UI defaults)
|
||||
/** @since 2 */ @Styleable protected int arc = -1;
|
||||
|
||||
private final boolean shared;
|
||||
private PropertyChangeListener propertyChangeListener;
|
||||
private Map<String, Object> oldStyleValues;
|
||||
@@ -113,4 +120,34 @@ public class FlatPanelUI
|
||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update( Graphics g, JComponent c ) {
|
||||
// fill background
|
||||
if( c.isOpaque() ) {
|
||||
int width = c.getWidth();
|
||||
int height = c.getHeight();
|
||||
int arc = (this.arc >= 0)
|
||||
? this.arc
|
||||
: ((c.getBorder() instanceof FlatLineBorder)
|
||||
? ((FlatLineBorder)c.getBorder()).getArc()
|
||||
: 0);
|
||||
|
||||
// fill background with parent color to avoid garbage in rounded corners
|
||||
if( arc > 0 )
|
||||
FlatUIUtils.paintParentBackground( g, c );
|
||||
|
||||
g.setColor( c.getBackground() );
|
||||
if( arc > 0 ) {
|
||||
// fill rounded rectangle if having rounded corners
|
||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||
FlatUIUtils.paintComponentBackground( (Graphics2D) g, 0, 0, width, height,
|
||||
0, UIScale.scale( arc ) );
|
||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||
} else
|
||||
g.fillRect( 0, 0, width, height );
|
||||
}
|
||||
|
||||
paint( g, c );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,12 @@ import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Insets;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.UIDefaults.ActiveValue;
|
||||
import javax.swing.UIDefaults.LazyValue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -46,8 +50,8 @@ public class TestUIDefaultsLoader
|
||||
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", null ) );
|
||||
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummyWidth", "1.23", null ) );
|
||||
|
||||
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummyInsets", "2,2,2,2", null ) );
|
||||
assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummySize", "2,2", null ) );
|
||||
assertEquals( new Insets( 1,2,3,4 ), UIDefaultsLoader.parseValue( "dummyInsets", "1,2,3,4", null ) );
|
||||
assertEquals( new Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummySize", "1,2", null ) );
|
||||
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", null ) );
|
||||
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummyColor", "#f00", null ) );
|
||||
}
|
||||
@@ -70,11 +74,35 @@ public class TestUIDefaultsLoader
|
||||
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", float.class ) );
|
||||
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", Float.class ) );
|
||||
|
||||
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2,2,2", Insets.class ) );
|
||||
assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2", Dimension.class ) );
|
||||
assertEquals( new Insets( 1,2,3,4 ), UIDefaultsLoader.parseValue( "dummy", "1,2,3,4", Insets.class ) );
|
||||
assertEquals( new Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummy", "1,2", Dimension.class ) );
|
||||
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", Color.class ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseBorders() {
|
||||
Insets insets = new Insets( 1,2,3,4 );
|
||||
assertBorderEquals( new FlatEmptyBorder( insets ), "1,2,3,4" );
|
||||
assertBorderEquals( new FlatLineBorder( insets, Color.red ), "1,2,3,4,#f00" );
|
||||
assertBorderEquals( new FlatLineBorder( insets, Color.red, 2.5f, 0 ), "1,2,3,4,#f00,2.5" );
|
||||
assertBorderEquals( new FlatLineBorder( insets, Color.red, 2.5f, 6 ), "1,2,3,4,#f00,2.5,6" );
|
||||
assertBorderEquals( new FlatLineBorder( insets, Color.red, 1, 6 ), "1,2,3,4,#f00,,6" );
|
||||
}
|
||||
|
||||
private void assertBorderEquals( Border expected, String actualStyle ) {
|
||||
Border actual = (Border) ((LazyValue)UIDefaultsLoader.parseValue( "dummyBorder", actualStyle, null )).createValue( null );
|
||||
assertEquals( expected.getClass(), actual.getClass() );
|
||||
if( expected instanceof FlatEmptyBorder )
|
||||
assertEquals( ((FlatEmptyBorder)actual).getBorderInsets(), ((FlatEmptyBorder)expected).getBorderInsets() );
|
||||
if( expected instanceof FlatLineBorder ) {
|
||||
FlatLineBorder a = (FlatLineBorder) actual;
|
||||
FlatLineBorder e = (FlatLineBorder) expected;
|
||||
assertEquals( a.getLineColor(), e.getLineColor() );
|
||||
assertEquals( a.getLineThickness(), e.getLineThickness() );
|
||||
assertEquals( a.getArc(), e.getArc() );
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseFonts() {
|
||||
// style
|
||||
|
||||
@@ -386,6 +386,7 @@ public class TestFlatStyleableInfo
|
||||
FlatPanelUI ui = (FlatPanelUI) c.getUI();
|
||||
|
||||
Map<String, Class<?>> expected = expectedMap(
|
||||
"arc", int.class
|
||||
);
|
||||
|
||||
assertMapEquals( expected, ui.getStyleableInfos( c ) );
|
||||
|
||||
@@ -529,6 +529,8 @@ public class TestFlatStyling
|
||||
JPanel c = new JPanel();
|
||||
FlatPanelUI ui = (FlatPanelUI) c.getUI();
|
||||
|
||||
ui.applyStyle( c, "arc: 8" );
|
||||
|
||||
// JComponent properties
|
||||
ui.applyStyle( c, "background: #fff" );
|
||||
ui.applyStyle( c, "foreground: #fff" );
|
||||
|
||||
@@ -194,7 +194,7 @@ class FlatColorPipette
|
||||
|
||||
zoom = UIScale.scale( 16 );
|
||||
|
||||
getRootPane().setBorder( new FlatLineBorder( new Insets( 2, 2, 2, 2 ), Color.red, 2 ) );
|
||||
getRootPane().setBorder( new FlatLineBorder( new Insets( 2, 2, 2, 2 ), Color.red, 2, 0 ) );
|
||||
|
||||
view = new MagnifierView();
|
||||
view.setPreferredSize( new Dimension( pixels * zoom, pixels * zoom ) );
|
||||
|
||||
Reference in New Issue
Block a user