From 0cdfd29ecfa70c89905cf7f803d499feff721909 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 30 Dec 2021 11:24:48 +0100 Subject: [PATCH] Extras: fixed concurrent loading of SVG icons on multiple threads (issue #459) --- CHANGELOG.md | 2 ++ .../formdev/flatlaf/extras/FlatSVGIcon.java | 8 +++-- .../flatlaf/testing/FlatStressTest.java | 29 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3e831e7..be93e860 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,8 @@ FlatLaf Change Log - Improved hover/pressed/selected colors of leading/trailing buttons (e.g. "reveal" button in password field). (issue #452) - Clear button no longer paints over round border. (issue #451) +- Extras: Fixed concurrent loading of SVG icons on multiple threads. (issue + #459) ## 2.0-rc1 diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java index ec1687ba..3a35f803 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java @@ -273,10 +273,12 @@ public class FlatSVGIcon // since the input stream is already loaded and parsed, // get diagram here and remove it from cache update(); - svgCache.remove( uri ); + synchronized( FlatSVGIcon.class ) { + svgCache.remove( uri ); + } } - private static URI loadFromStream( InputStream in ) throws IOException { + private static synchronized URI loadFromStream( InputStream in ) throws IOException { try( InputStream in2 = in ) { return svgUniverse.loadSVG( in2, "/flatlaf-stream-" + (streamNumber++) ); } @@ -475,7 +477,7 @@ public class FlatSVGIcon loadFailed = (diagram == null); } - static SVGDiagram loadSVG( URI uri ) { + static synchronized SVGDiagram loadSVG( URI uri ) { // get from our cache SVGDiagram diagram = svgCache.get( uri ); if( diagram != null ) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatStressTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatStressTest.java index da44cba9..f2993e52 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatStressTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatStressTest.java @@ -27,6 +27,7 @@ import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatLightLaf; +import com.formdev.flatlaf.extras.FlatSVGIcon; /** * @author Karl Tauber @@ -57,6 +58,7 @@ public class FlatStressTest private JComponent createStressTest() { return createComboBoxStressTest(); // return createGetFontStressTest(); +// return createSVGIconTest(); } // for https://github.com/JFormDesigner/FlatLaf/issues/432 @@ -109,4 +111,31 @@ public class FlatStressTest return label; } + + // for https://github.com/JFormDesigner/FlatLaf/issues/459 + @SuppressWarnings( "unused" ) + private JComponent createSVGIconTest() { + JLabel label = new JLabel( "test" ); + + Runnable runnable = () -> { + for(;;) { + FlatSVGIcon icon = new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/back.svg" ); + icon.getIconHeight(); + } + }; + + Thread thread1 = new Thread( runnable); + thread1.setDaemon( true ); + thread1.start(); + + Thread thread2 = new Thread( runnable); + thread2.setDaemon( true ); + thread2.start(); + + Thread thread3 = new Thread( runnable); + thread3.setDaemon( true ); + thread3.start(); + + return label; + } }