Extras: FlatSVGIcon and FlatSVGUtils: use soft cache for SVG diagrams to allow freeing memory if no longer used

This commit is contained in:
Karl Tauber
2021-11-12 10:49:02 +01:00
parent ccdb981917
commit a2d66e91ff
2 changed files with 26 additions and 19 deletions

View File

@@ -48,6 +48,7 @@ import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.SoftCache;
import com.formdev.flatlaf.util.UIScale;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
@@ -62,6 +63,9 @@ public class FlatSVGIcon
extends ImageIcon
implements DisabledIconProvider
{
// cache that uses soft references for values, which allows freeing SVG diagrams if no longer used
private static final SoftCache<URI, SVGDiagram> svgCache = new SoftCache<>();
// use own SVG universe so that it can not be cleared from anywhere
private static final SVGUniverse svgUniverse = new SVGUniverse();
private static int streamNumber;
@@ -267,9 +271,9 @@ public class FlatSVGIcon
this( null, -1, -1, 1, false, null, loadFromStream( in ) );
// since the input stream is already loaded and parsed,
// get diagram here and remove it from SVGUniverse cache
// get diagram here and remove it from cache
update();
svgUniverse.removeDocument( uri );
svgCache.remove( uri );
}
private static URI loadFromStream( InputStream in ) throws IOException {
@@ -467,13 +471,29 @@ public class FlatSVGIcon
uri = url2uri( url );
}
// load/get image
diagram = loadSVG( uri );
loadFailed = (diagram == null);
}
static SVGDiagram loadSVG( URI uri ) {
// get from our cache
SVGDiagram diagram = svgCache.get( uri );
if( diagram != null )
return diagram;
// load/get SVG diagram
diagram = svgUniverse.getDiagram( uri );
if( diagram == null ) {
loadFailed = true;
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + uri + "'", null );
return null;
}
// add to our (soft) cache and remove from SVGUniverse (hard) cache
svgCache.put( uri, diagram );
svgUniverse.removeDocument( uri );
return diagram;
}
private URL getIconURL( String name, boolean dark ) {
@@ -623,7 +643,7 @@ public class FlatSVGIcon
return MultiResolutionImageSupport.create( 0, dimensions, producer );
}
private static URI url2uri( URL url ) {
static URI url2uri( URL url ) {
try {
return url.toURI();
} catch( URISyntaxException ex ) {

View File

@@ -21,7 +21,6 @@ import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
@@ -29,7 +28,6 @@ import java.util.List;
import javax.swing.JWindow;
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.SystemInfo;
import com.kitfox.svg.SVGCache;
import com.kitfox.svg.SVGDiagram;
import com.kitfox.svg.SVGException;
@@ -228,18 +226,7 @@ public class FlatSVGUtils
return FlatSVGUtils.class.getResource( svgName );
}
/**
* Loads a SVG file.
*
* @param url the URL of the SVG resource
* @return the SVG diagram
* @throws RuntimeException if failed to load SVG file
*/
private static SVGDiagram loadSVG( URL url ) {
try {
return SVGCache.getSVGUniverse().getDiagram( url.toURI() );
} catch( URISyntaxException ex ) {
throw new RuntimeException( ex );
}
return FlatSVGIcon.loadSVG( FlatSVGIcon.url2uri( url ) );
}
}