From db2452a4ec4856fa162deacf746423a75fe7aff3 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Tue, 30 Nov 2021 18:36:20 +0100 Subject: [PATCH] Styling: support Panel --- .../com/formdev/flatlaf/ui/FlatPanelUI.java | 77 ++++++++++++++++++- .../flatlaf/ui/TestFlatStyleClasses.java | 9 +++ .../flatlaf/ui/TestFlatStyleableInfo.java | 11 +++ .../formdev/flatlaf/ui/TestFlatStyling.java | 12 +++ 4 files changed, 108 insertions(+), 1 deletion(-) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPanelUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPanelUI.java index bbf15601..bec0549e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPanelUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPanelUI.java @@ -16,9 +16,14 @@ package com.formdev.flatlaf.ui; +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.StyleableUI; +import com.formdev.flatlaf.util.LoggingFacade; /** * Provides the Flat LaF UI delegate for {@link javax.swing.JPanel}. @@ -34,8 +39,78 @@ import javax.swing.plaf.basic.BasicPanelUI; */ public class FlatPanelUI extends BasicPanelUI + implements StyleableUI { + private final boolean shared; + private PropertyChangeListener propertyChangeListener; + private Map oldStyleValues; + public static ComponentUI createUI( JComponent c ) { - return FlatUIUtils.createSharedUI( FlatPanelUI.class, FlatPanelUI::new ); + return FlatUIUtils.canUseSharedUI( c ) + ? FlatUIUtils.createSharedUI( FlatPanelUI.class, () -> new FlatPanelUI( true ) ) + : new FlatPanelUI( false ); + } + + /** @since 2 */ + protected FlatPanelUI( boolean shared ) { + this.shared = shared; + } + + @Override + public void installUI( JComponent c ) { + super.installUI( c ); + + propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( + c, () -> stylePropertyChange( (JPanel) c ), null ); + c.addPropertyChangeListener( propertyChangeListener ); + + installStyle( (JPanel) c ); + } + + @Override + public void uninstallUI( JComponent c ) { + super.uninstallUI( c ); + + c.removePropertyChangeListener( propertyChangeListener ); + propertyChangeListener = null; + + oldStyleValues = null; + } + + private void stylePropertyChange( JPanel c ) { + if( shared && FlatStylingSupport.hasStyleProperty( c ) ) { + // unshare component UI if necessary + // updateUI() invokes installStyle() from installUI() + c.updateUI(); + } else + installStyle( c ); + c.revalidate(); + c.repaint(); + } + + /** @since 2 */ + protected void installStyle( JPanel c ) { + try { + applyStyle( c, FlatStylingSupport.getResolvedStyle( c, "Panel" ) ); + } catch( RuntimeException ex ) { + LoggingFacade.INSTANCE.logSevere( null, ex ); + } + } + + /** @since 2 */ + protected void applyStyle( JPanel c, Object style ) { + oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, + (key, value) -> applyStyleProperty( c, key, value ) ); + } + + /** @since 2 */ + protected Object applyStyleProperty( JPanel c, String key, Object value ) { + return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, c, key, value ); + } + + /** @since 2 */ + @Override + public Map> getStyleableInfos( JComponent c ) { + return FlatStylingSupport.getAnnotatedStyleableInfos( this ); } } diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java index 20bb9ebe..84e25f27 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleClasses.java @@ -61,6 +61,7 @@ public class TestFlatStyleClasses UIManager.put( "[style]MenuItem.test", "foreground: #000011" ); UIManager.put( "[style]CheckBoxMenuItem.test", "foreground: #000012" ); UIManager.put( "[style]RadioButtonMenuItem.test", "foreground: #000013" ); + UIManager.put( "[style]Panel.test", "foreground: #000034" ); UIManager.put( "[style]PasswordField.test", "foreground: #000014" ); UIManager.put( "[style]PopupMenu.test", "foreground: #000015" ); UIManager.put( "[style]PopupMenuSeparator.test", "foreground: #000016" ); @@ -278,6 +279,14 @@ public class TestFlatStyleClasses assertEquals( new Color( 0x000013 ), c.getForeground() ); } + @Test + void panel() { + JPanel c = new JPanel(); + c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" ); + assertEquals( Color.magenta, c.getBackground() ); + assertEquals( new Color( 0x000034 ), c.getForeground() ); + } + @Test void passwordField() { JPasswordField c = new JPasswordField(); diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java index 2a4f2c1a..4b4c1665 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java @@ -379,6 +379,17 @@ public class TestFlatStyleableInfo ); } + @Test + void panel() { + JPanel c = new JPanel(); + FlatPanelUI ui = (FlatPanelUI) c.getUI(); + + Map> expected = expectedMap( + ); + + assertMapEquals( expected, ui.getStyleableInfos( c ) ); + } + @Test void passwordField() { JPasswordField c = new JPasswordField(); diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index ea783889..7ea73961 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -523,6 +523,18 @@ public class TestFlatStyling applyStyle.accept( "selectionForeground: #fff" ); } + @Test + void panel() { + JPanel c = new JPanel(); + FlatPanelUI ui = (FlatPanelUI) c.getUI(); + + // JComponent properties + ui.applyStyle( c, "background: #fff" ); + ui.applyStyle( c, "foreground: #fff" ); + ui.applyStyle( c, "border: 2,2,2,2,#f00" ); + ui.applyStyle( c, "font: italic 12 monospaced" ); + } + @Test void passwordField() { JPasswordField c = new JPasswordField();