From 936de607007792c880f5837175a1b961f8256332 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 24 Jan 2022 18:28:38 +0100 Subject: [PATCH] fixed memory leak in Panel, Separator and ToolBarSeparator (issue #471) --- CHANGELOG.md | 5 +++ build.gradle.kts | 2 +- .../com/formdev/flatlaf/ui/FlatPanelUI.java | 38 +++++++++++-------- .../formdev/flatlaf/ui/FlatSeparatorUI.java | 38 +++++++++++-------- .../flatlaf/ui/FlatToolBarSeparatorUI.java | 38 +++++++++++-------- .../com/formdev/flatlaf/ui/FlatToolTipUI.java | 28 +++++++------- 6 files changed, 86 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60795811..5850eebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ FlatLaf Change Log ================== +## 2.0.1-SNAPSHOT + +- Fixed memory leak in Panel, Separator and ToolBarSeparator. (issue #471) + + ## 2.0 - Added system property `flatlaf.nativeLibraryPath` to load native libraries diff --git a/build.gradle.kts b/build.gradle.kts index 429be7e9..f50bd33e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ */ val releaseVersion = "2.0" -val developmentVersion = "2.1-SNAPSHOT" +val developmentVersion = "2.0.1-SNAPSHOT" version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion 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 61ea6719..5718611d 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 @@ -18,12 +18,14 @@ package com.formdev.flatlaf.ui; import java.awt.Graphics; import java.awt.Graphics2D; +import java.beans.PropertyChangeEvent; 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.FlatClientProperties; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.util.LoggingFacade; @@ -43,13 +45,12 @@ import com.formdev.flatlaf.util.UIScale; */ public class FlatPanelUI extends BasicPanelUI - implements StyleableUI + implements StyleableUI, PropertyChangeListener { // only used via styling (not in UI defaults) /** @since 2 */ @Styleable protected int arc = -1; private final boolean shared; - private PropertyChangeListener propertyChangeListener; private Map oldStyleValues; public static ComponentUI createUI( JComponent c ) { @@ -67,9 +68,7 @@ public class FlatPanelUI public void installUI( JComponent c ) { super.installUI( c ); - propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( - c, () -> stylePropertyChange( (JPanel) c ), null ); - c.addPropertyChangeListener( propertyChangeListener ); + c.addPropertyChangeListener( this ); installStyle( (JPanel) c ); } @@ -78,21 +77,28 @@ public class FlatPanelUI public void uninstallUI( JComponent c ) { super.uninstallUI( c ); - c.removePropertyChangeListener( propertyChangeListener ); - propertyChangeListener = null; + c.removePropertyChangeListener( this ); 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.0.1 */ + @Override + public void propertyChange( PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case FlatClientProperties.STYLE: + case FlatClientProperties.STYLE_CLASS: + JPanel c = (JPanel) e.getSource(); + if( shared && FlatStylingSupport.hasStyleProperty( c ) ) { + // unshare component UI if necessary + // updateUI() invokes installStyle() from installUI() + c.updateUI(); + } else + installStyle( c ); + c.revalidate(); + c.repaint(); + break; + } } /** @since 2 */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java index 8485b30f..ac02e4b9 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatSeparatorUI.java @@ -21,6 +21,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Map; import javax.swing.JComponent; @@ -28,6 +29,7 @@ import javax.swing.JSeparator; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicSeparatorUI; +import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.util.LoggingFacade; @@ -50,7 +52,7 @@ import com.formdev.flatlaf.util.LoggingFacade; */ public class FlatSeparatorUI extends BasicSeparatorUI - implements StyleableUI + implements StyleableUI, PropertyChangeListener { @Styleable protected int height; @Styleable protected int stripeWidth; @@ -58,7 +60,6 @@ public class FlatSeparatorUI private final boolean shared; private boolean defaults_initialized = false; - private PropertyChangeListener propertyChangeListener; private Map oldStyleValues; public static ComponentUI createUI( JComponent c ) { @@ -109,28 +110,33 @@ public class FlatSeparatorUI protected void installListeners( JSeparator s ) { super.installListeners( s ); - propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( - s, () -> stylePropertyChange( s ), null ); - s.addPropertyChangeListener( propertyChangeListener ); + s.addPropertyChangeListener( this ); } @Override protected void uninstallListeners( JSeparator s ) { super.uninstallListeners( s ); - s.removePropertyChangeListener( propertyChangeListener ); - propertyChangeListener = null; + s.removePropertyChangeListener( this ); } - private void stylePropertyChange( JSeparator s ) { - if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { - // unshare component UI if necessary - // updateUI() invokes installStyle() from installUI() - s.updateUI(); - } else - installStyle( s ); - s.revalidate(); - s.repaint(); + /** @since 2.0.1 */ + @Override + public void propertyChange( PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case FlatClientProperties.STYLE: + case FlatClientProperties.STYLE_CLASS: + JSeparator s = (JSeparator) e.getSource(); + if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { + // unshare component UI if necessary + // updateUI() invokes installStyle() from installUI() + s.updateUI(); + } else + installStyle( s ); + s.revalidate(); + s.repaint(); + break; + } } /** @since 2 */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java index 06323b17..5f3bfa27 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolBarSeparatorUI.java @@ -22,6 +22,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Map; import javax.swing.JComponent; @@ -31,6 +32,7 @@ import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicToolBarSeparatorUI; +import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.util.LoggingFacade; @@ -47,7 +49,7 @@ import com.formdev.flatlaf.util.LoggingFacade; */ public class FlatToolBarSeparatorUI extends BasicToolBarSeparatorUI - implements StyleableUI + implements StyleableUI, PropertyChangeListener { private static final int LINE_WIDTH = 1; @@ -56,7 +58,6 @@ public class FlatToolBarSeparatorUI private final boolean shared; private boolean defaults_initialized = false; - private PropertyChangeListener propertyChangeListener; private Map oldStyleValues; public static ComponentUI createUI( JComponent c ) { @@ -105,28 +106,33 @@ public class FlatToolBarSeparatorUI protected void installListeners( JSeparator s ) { super.installListeners( s ); - propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( - s, () -> stylePropertyChange( s ), null ); - s.addPropertyChangeListener( propertyChangeListener ); + s.addPropertyChangeListener( this ); } @Override protected void uninstallListeners( JSeparator s ) { super.uninstallListeners( s ); - s.removePropertyChangeListener( propertyChangeListener ); - propertyChangeListener = null; + s.removePropertyChangeListener( this ); } - private void stylePropertyChange( JSeparator s ) { - if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { - // unshare component UI if necessary - // updateUI() invokes installStyle() from installUI() - s.updateUI(); - } else - installStyle( s ); - s.revalidate(); - s.repaint(); + /** @since 2.0.1 */ + @Override + public void propertyChange( PropertyChangeEvent e ) { + switch( e.getPropertyName() ) { + case FlatClientProperties.STYLE: + case FlatClientProperties.STYLE_CLASS: + JSeparator s = (JSeparator) e.getSource(); + if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { + // unshare component UI if necessary + // updateUI() invokes installStyle() from installUI() + s.updateUI(); + } else + installStyle( s ); + s.revalidate(); + s.repaint(); + break; + } } /** @since 2 */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java index 8428f0ae..142f2a97 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatToolTipUI.java @@ -21,6 +21,7 @@ import java.awt.FontMetrics; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; import javax.swing.JComponent; @@ -49,9 +50,8 @@ import com.formdev.flatlaf.util.StringUtils; */ public class FlatToolTipUI extends BasicToolTipUI + implements PropertyChangeListener { - private static PropertyChangeListener sharedPropertyChangedListener; - public static ComponentUI createUI( JComponent c ) { return FlatUIUtils.createSharedUI( FlatToolTipUI.class, FlatToolTipUI::new ); } @@ -68,24 +68,24 @@ public class FlatToolTipUI protected void installListeners( JComponent c ) { super.installListeners( c ); - if( sharedPropertyChangedListener == null ) { - sharedPropertyChangedListener = e -> { - String name = e.getPropertyName(); - if( name == "tiptext" || name == "font" || name == "foreground" ) { - JToolTip toolTip = (JToolTip) e.getSource(); - FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false ); - } - }; - } - - c.addPropertyChangeListener( sharedPropertyChangedListener ); + c.addPropertyChangeListener( this ); } @Override protected void uninstallListeners( JComponent c ) { super.uninstallListeners( c ); - c.removePropertyChangeListener( sharedPropertyChangedListener ); + c.removePropertyChangeListener( this ); + } + + /** @since 2.0.1 */ + @Override + public void propertyChange( PropertyChangeEvent e ) { + String name = e.getPropertyName(); + if( name == "tiptext" || name == "font" || name == "foreground" ) { + JToolTip toolTip = (JToolTip) e.getSource(); + FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false ); + } } @Override