fixed memory leak in Panel, Separator and ToolBarSeparator (issue #471)

This commit is contained in:
Karl Tauber
2022-01-24 18:28:38 +01:00
parent f6b64d48ec
commit 936de60700
6 changed files with 86 additions and 63 deletions

View File

@@ -1,6 +1,11 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 2.0.1-SNAPSHOT
- Fixed memory leak in Panel, Separator and ToolBarSeparator. (issue #471)
## 2.0 ## 2.0
- Added system property `flatlaf.nativeLibraryPath` to load native libraries - Added system property `flatlaf.nativeLibraryPath` to load native libraries

View File

@@ -15,7 +15,7 @@
*/ */
val releaseVersion = "2.0" 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 version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion

View File

@@ -18,12 +18,14 @@ package com.formdev.flatlaf.ui;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Map; import java.util.Map;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPanelUI; import javax.swing.plaf.basic.BasicPanelUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -43,13 +45,12 @@ import com.formdev.flatlaf.util.UIScale;
*/ */
public class FlatPanelUI public class FlatPanelUI
extends BasicPanelUI extends BasicPanelUI
implements StyleableUI implements StyleableUI, PropertyChangeListener
{ {
// only used via styling (not in UI defaults) // only used via styling (not in UI defaults)
/** @since 2 */ @Styleable protected int arc = -1; /** @since 2 */ @Styleable protected int arc = -1;
private final boolean shared; private final boolean shared;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -67,9 +68,7 @@ public class FlatPanelUI
public void installUI( JComponent c ) { public void installUI( JComponent c ) {
super.installUI( c ); super.installUI( c );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( c.addPropertyChangeListener( this );
c, () -> stylePropertyChange( (JPanel) c ), null );
c.addPropertyChangeListener( propertyChangeListener );
installStyle( (JPanel) c ); installStyle( (JPanel) c );
} }
@@ -78,13 +77,18 @@ public class FlatPanelUI
public void uninstallUI( JComponent c ) { public void uninstallUI( JComponent c ) {
super.uninstallUI( c ); super.uninstallUI( c );
c.removePropertyChangeListener( propertyChangeListener ); c.removePropertyChangeListener( this );
propertyChangeListener = null;
oldStyleValues = null; oldStyleValues = null;
} }
private void stylePropertyChange( JPanel c ) { /** @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 ) ) { if( shared && FlatStylingSupport.hasStyleProperty( c ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes installStyle() from installUI()
@@ -93,6 +97,8 @@ public class FlatPanelUI
installStyle( c ); installStyle( c );
c.revalidate(); c.revalidate();
c.repaint(); c.repaint();
break;
}
} }
/** @since 2 */ /** @since 2 */

View File

@@ -21,6 +21,7 @@ import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Map; import java.util.Map;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -28,6 +29,7 @@ import javax.swing.JSeparator;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSeparatorUI; import javax.swing.plaf.basic.BasicSeparatorUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -50,7 +52,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
*/ */
public class FlatSeparatorUI public class FlatSeparatorUI
extends BasicSeparatorUI extends BasicSeparatorUI
implements StyleableUI implements StyleableUI, PropertyChangeListener
{ {
@Styleable protected int height; @Styleable protected int height;
@Styleable protected int stripeWidth; @Styleable protected int stripeWidth;
@@ -58,7 +60,6 @@ public class FlatSeparatorUI
private final boolean shared; private final boolean shared;
private boolean defaults_initialized = false; private boolean defaults_initialized = false;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -109,20 +110,23 @@ public class FlatSeparatorUI
protected void installListeners( JSeparator s ) { protected void installListeners( JSeparator s ) {
super.installListeners( s ); super.installListeners( s );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( s.addPropertyChangeListener( this );
s, () -> stylePropertyChange( s ), null );
s.addPropertyChangeListener( propertyChangeListener );
} }
@Override @Override
protected void uninstallListeners( JSeparator s ) { protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s ); super.uninstallListeners( s );
s.removePropertyChangeListener( propertyChangeListener ); s.removePropertyChangeListener( this );
propertyChangeListener = null;
} }
private void stylePropertyChange( JSeparator s ) { /** @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 ) ) { if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes installStyle() from installUI()
@@ -131,6 +135,8 @@ public class FlatSeparatorUI
installStyle( s ); installStyle( s );
s.revalidate(); s.revalidate();
s.repaint(); s.repaint();
break;
}
} }
/** @since 2 */ /** @since 2 */

View File

@@ -22,6 +22,7 @@ import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Map; import java.util.Map;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -31,6 +32,7 @@ import javax.swing.SwingConstants;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarSeparatorUI; import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -47,7 +49,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
*/ */
public class FlatToolBarSeparatorUI public class FlatToolBarSeparatorUI
extends BasicToolBarSeparatorUI extends BasicToolBarSeparatorUI
implements StyleableUI implements StyleableUI, PropertyChangeListener
{ {
private static final int LINE_WIDTH = 1; private static final int LINE_WIDTH = 1;
@@ -56,7 +58,6 @@ public class FlatToolBarSeparatorUI
private final boolean shared; private final boolean shared;
private boolean defaults_initialized = false; private boolean defaults_initialized = false;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -105,20 +106,23 @@ public class FlatToolBarSeparatorUI
protected void installListeners( JSeparator s ) { protected void installListeners( JSeparator s ) {
super.installListeners( s ); super.installListeners( s );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( s.addPropertyChangeListener( this );
s, () -> stylePropertyChange( s ), null );
s.addPropertyChangeListener( propertyChangeListener );
} }
@Override @Override
protected void uninstallListeners( JSeparator s ) { protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s ); super.uninstallListeners( s );
s.removePropertyChangeListener( propertyChangeListener ); s.removePropertyChangeListener( this );
propertyChangeListener = null;
} }
private void stylePropertyChange( JSeparator s ) { /** @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 ) ) { if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes installStyle() from installUI()
@@ -127,6 +131,8 @@ public class FlatToolBarSeparatorUI
installStyle( s ); installStyle( s );
s.revalidate(); s.revalidate();
s.repaint(); s.repaint();
break;
}
} }
/** @since 2 */ /** @since 2 */

View File

@@ -21,6 +21,7 @@ import java.awt.FontMetrics;
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.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.List; import java.util.List;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -49,9 +50,8 @@ import com.formdev.flatlaf.util.StringUtils;
*/ */
public class FlatToolTipUI public class FlatToolTipUI
extends BasicToolTipUI extends BasicToolTipUI
implements PropertyChangeListener
{ {
private static PropertyChangeListener sharedPropertyChangedListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return FlatUIUtils.createSharedUI( FlatToolTipUI.class, FlatToolTipUI::new ); return FlatUIUtils.createSharedUI( FlatToolTipUI.class, FlatToolTipUI::new );
} }
@@ -68,24 +68,24 @@ public class FlatToolTipUI
protected void installListeners( JComponent c ) { protected void installListeners( JComponent c ) {
super.installListeners( c ); super.installListeners( c );
if( sharedPropertyChangedListener == null ) { c.addPropertyChangeListener( this );
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 );
} }
@Override @Override
protected void uninstallListeners( JComponent c ) { protected void uninstallListeners( JComponent c ) {
super.uninstallListeners( 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 @Override