Styling: support InternalFrame

This commit is contained in:
Karl Tauber
2021-07-20 08:57:21 +02:00
parent e3e8765b91
commit 7fd64a1b73
4 changed files with 119 additions and 11 deletions

View File

@@ -24,6 +24,8 @@ import java.awt.Image;
import java.awt.Insets; import java.awt.Insets;
import java.awt.RadialGradientPaint; import java.awt.RadialGradientPaint;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStyleSupport.StyleableBorder;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
@@ -40,14 +42,17 @@ import com.formdev.flatlaf.util.UIScale;
*/ */
public class FlatDropShadowBorder public class FlatDropShadowBorder
extends FlatEmptyBorder extends FlatEmptyBorder
implements StyleableBorder
{ {
private final Color shadowColor; @Styleable protected Color shadowColor;
private final Insets shadowInsets; @Styleable protected Insets shadowInsets;
private final float shadowOpacity; @Styleable protected float shadowOpacity;
private final int shadowSize; private int shadowSize;
private Image shadowImage; private Image shadowImage;
private Color lastShadowColor; private Color lastShadowColor;
private float lastShadowOpacity;
private int lastShadowSize;
private double lastSystemScaleFactor; private double lastSystemScaleFactor;
private float lastUserScaleFactor; private float lastUserScaleFactor;
@@ -64,17 +69,36 @@ public class FlatDropShadowBorder
} }
public FlatDropShadowBorder( Color shadowColor, Insets shadowInsets, float shadowOpacity ) { public FlatDropShadowBorder( Color shadowColor, Insets shadowInsets, float shadowOpacity ) {
super( Math.max( shadowInsets.top, 0 ), Math.max( shadowInsets.left, 0 ), super( nonNegativeInsets( shadowInsets ) );
Math.max( shadowInsets.bottom, 0 ), Math.max( shadowInsets.right, 0 ) );
this.shadowColor = shadowColor; this.shadowColor = shadowColor;
this.shadowInsets = shadowInsets; this.shadowInsets = shadowInsets;
this.shadowOpacity = shadowOpacity; this.shadowOpacity = shadowOpacity;
shadowSize = Math.max( shadowSize = maxInset( shadowInsets );
}
private static Insets nonNegativeInsets( Insets shadowInsets ) {
return new Insets( Math.max( shadowInsets.top, 0 ), Math.max( shadowInsets.left, 0 ),
Math.max( shadowInsets.bottom, 0 ), Math.max( shadowInsets.right, 0 ) );
}
private int maxInset( Insets shadowInsets ) {
return Math.max(
Math.max( shadowInsets.left, shadowInsets.right ), Math.max( shadowInsets.left, shadowInsets.right ),
Math.max( shadowInsets.top, shadowInsets.bottom ) ); Math.max( shadowInsets.top, shadowInsets.bottom ) );
} }
@Override
public Object applyStyleProperty( String key, Object value ) {
Object oldValue = FlatStyleSupport.applyToAnnotatedObject( this, key, value );
if( key.equals( "shadowInsets" ) ) {
applyStyleProperty( nonNegativeInsets( shadowInsets ) );
shadowSize = maxInset( shadowInsets );
}
return oldValue;
}
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( shadowSize <= 0 ) if( shadowSize <= 0 )
@@ -91,12 +115,16 @@ public class FlatDropShadowBorder
float userScaleFactor = UIScale.getUserScaleFactor(); float userScaleFactor = UIScale.getUserScaleFactor();
if( shadowImage == null || if( shadowImage == null ||
!shadowColor.equals( lastShadowColor ) || !shadowColor.equals( lastShadowColor ) ||
lastShadowOpacity != shadowOpacity ||
lastShadowSize != shadowSize ||
lastSystemScaleFactor != scaleFactor || lastSystemScaleFactor != scaleFactor ||
lastUserScaleFactor != userScaleFactor ) lastUserScaleFactor != userScaleFactor )
{ {
shadowImage = createShadowImage( shadowColor, shadowSize, shadowOpacity, shadowImage = createShadowImage( shadowColor, shadowSize, shadowOpacity,
(float) (scaleFactor * userScaleFactor) ); (float) (scaleFactor * userScaleFactor) );
lastShadowColor = shadowColor; lastShadowColor = shadowColor;
lastShadowOpacity = shadowOpacity;
lastShadowSize = shadowSize;
lastSystemScaleFactor = scaleFactor; lastSystemScaleFactor = scaleFactor;
lastUserScaleFactor = userScaleFactor; lastUserScaleFactor = userScaleFactor;
} }

View File

@@ -67,4 +67,13 @@ public class FlatEmptyBorder
public Insets getUnscaledBorderInsets() { public Insets getUnscaledBorderInsets() {
return super.getBorderInsets(); return super.getBorderInsets();
} }
public Object applyStyleProperty( Insets insets ) {
Insets oldInsets = getUnscaledBorderInsets();
top = insets.top;
left = insets.left;
bottom = insets.bottom;
right = insets.right;
return oldInsets;
}
} }

View File

@@ -22,12 +22,17 @@ import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.beans.PropertyChangeListener;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JInternalFrame; import javax.swing.JInternalFrame;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicInternalFrameUI; import javax.swing.plaf.basic.BasicInternalFrameUI;
import com.formdev.flatlaf.ui.FlatStyleSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStyleSupport.StyleableBorder;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame}. * Provides the Flat LaF UI delegate for {@link javax.swing.JInternalFrame}.
@@ -86,6 +91,9 @@ public class FlatInternalFrameUI
{ {
protected FlatWindowResizer windowResizer; protected FlatWindowResizer windowResizer;
private Map<String, Object> oldStyleValues;
private AtomicBoolean borderShared;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatInternalFrameUI( (JInternalFrame) c ); return new FlatInternalFrameUI( (JInternalFrame) c );
} }
@@ -101,6 +109,8 @@ public class FlatInternalFrameUI
LookAndFeel.installProperty( frame, "opaque", false ); LookAndFeel.installProperty( frame, "opaque", false );
windowResizer = createWindowResizer(); windowResizer = createWindowResizer();
applyStyle( FlatStyleSupport.getStyle( c ) );
} }
@Override @Override
@@ -111,6 +121,9 @@ public class FlatInternalFrameUI
windowResizer.uninstall(); windowResizer.uninstall();
windowResizer = null; windowResizer = null;
} }
oldStyleValues = null;
borderShared = null;
} }
@Override @Override
@@ -122,15 +135,38 @@ public class FlatInternalFrameUI
return new FlatWindowResizer.InternalFrameResizer( frame, this::getDesktopManager ); return new FlatWindowResizer.InternalFrameResizer( frame, this::getDesktopManager );
} }
@Override
protected PropertyChangeListener createPropertyChangeListener() {
return FlatStyleSupport.createPropertyChangeListener( frame, this::applyStyle,
super.createPropertyChangeListener() );
}
/**
* @since TODO
*/
protected void applyStyle( Object style ) {
oldStyleValues = FlatStyleSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
}
/**
* @since TODO
*/
protected Object applyStyleProperty( String key, Object value ) {
if( borderShared == null )
borderShared = new AtomicBoolean( true );
return FlatStyleSupport.applyToAnnotatedObjectOrBorder( this, key, value, frame, borderShared );
}
//---- class FlatInternalFrameBorder -------------------------------------- //---- class FlatInternalFrameBorder --------------------------------------
public static class FlatInternalFrameBorder public static class FlatInternalFrameBorder
extends FlatEmptyBorder extends FlatEmptyBorder
implements StyleableBorder
{ {
private final Color activeBorderColor = UIManager.getColor( "InternalFrame.activeBorderColor" ); @Styleable protected Color activeBorderColor = UIManager.getColor( "InternalFrame.activeBorderColor" );
private final Color inactiveBorderColor = UIManager.getColor( "InternalFrame.inactiveBorderColor" ); @Styleable protected Color inactiveBorderColor = UIManager.getColor( "InternalFrame.inactiveBorderColor" );
private final int borderLineWidth = FlatUIUtils.getUIInt( "InternalFrame.borderLineWidth", 1 ); @Styleable protected int borderLineWidth = FlatUIUtils.getUIInt( "InternalFrame.borderLineWidth", 1 );
private final boolean dropShadowPainted = UIManager.getBoolean( "InternalFrame.dropShadowPainted" ); @Styleable protected boolean dropShadowPainted = UIManager.getBoolean( "InternalFrame.dropShadowPainted" );
private final FlatDropShadowBorder activeDropShadowBorder = new FlatDropShadowBorder( private final FlatDropShadowBorder activeDropShadowBorder = new FlatDropShadowBorder(
UIManager.getColor( "InternalFrame.activeDropShadowColor" ), UIManager.getColor( "InternalFrame.activeDropShadowColor" ),
@@ -145,6 +181,22 @@ public class FlatInternalFrameUI
super( UIManager.getInsets( "InternalFrame.borderMargins" ) ); super( UIManager.getInsets( "InternalFrame.borderMargins" ) );
} }
@Override
public Object applyStyleProperty( String key, Object value ) {
switch( key ) {
case "borderMargins": return applyStyleProperty( (Insets) value );
case "activeDropShadowColor": return activeDropShadowBorder.applyStyleProperty( "shadowColor", value );
case "activeDropShadowInsets": return activeDropShadowBorder.applyStyleProperty( "shadowInsets", value );
case "activeDropShadowOpacity": return activeDropShadowBorder.applyStyleProperty( "shadowOpacity", value );
case "inactiveDropShadowColor": return inactiveDropShadowBorder.applyStyleProperty( "shadowColor", value );
case "inactiveDropShadowInsets": return inactiveDropShadowBorder.applyStyleProperty( "shadowInsets", value );
case "inactiveDropShadowOpacity": return inactiveDropShadowBorder.applyStyleProperty( "shadowOpacity", value );
}
return FlatStyleSupport.applyToAnnotatedObject( this, key, value );
}
@Override @Override
public Insets getBorderInsets( Component c, Insets insets ) { public Insets getBorderInsets( Component c, Insets insets ) {
if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) { if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) {

View File

@@ -197,6 +197,25 @@ public class TestFlatStyling
textField( ui ); textField( ui );
} }
@Test
void internalFrame() {
JInternalFrame c = new JInternalFrame();
FlatInternalFrameUI ui = (FlatInternalFrameUI) c.getUI();
ui.applyStyle( "activeBorderColor: #fff" );
ui.applyStyle( "inactiveBorderColor: #fff" );
ui.applyStyle( "borderLineWidth: 123" );
ui.applyStyle( "dropShadowPainted: false" );
ui.applyStyle( "borderMargins: 1,2,3,4" );
ui.applyStyle( "activeDropShadowColor: #fff" );
ui.applyStyle( "activeDropShadowInsets: 1,2,3,4" );
ui.applyStyle( "activeDropShadowOpacity: 0.5" );
ui.applyStyle( "inactiveDropShadowColor: #fff" );
ui.applyStyle( "inactiveDropShadowInsets: 1,2,3,4" );
ui.applyStyle( "inactiveDropShadowOpacity: 0.5" );
}
@Test @Test
void label() { void label() {
JLabel c = new JLabel(); JLabel c = new JLabel();