From d80b581ace6b1bfc37124ea63bf71eeb12f5e281 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Fri, 12 Nov 2021 09:28:24 +0100 Subject: [PATCH] Extras: FlatSVGUtils: support loading SVG from URL (for JPMS) (issue #325) --- CHANGELOG.md | 1 + .../formdev/flatlaf/extras/FlatSVGUtils.java | 84 +++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e3749c0..1d5fdc86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ FlatLaf Change Log (About, Preferences and Quit) when using Java 8. - `FlatSVGIcon`: Support loading SVG from `URL` (for JPMS), `URI`, `File` or `InputStream`. (issues #419 and #325) + - `FlatSVGUtils`: Support loading SVG from `URL` (for JPMS). (issue #325) #### Fixed bugs diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java index 08e308e9..e4a46bb1 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java @@ -50,6 +50,9 @@ public class FlatSVGUtils * for requested sizes from SVG. * This has the advantage that only images for used sizes are created. * Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG. + *

+ * If using Java modules, the package containing the SVG must be opened in {@code module-info.java}. + * Otherwise use {@link #createWindowIconImages(URL)}. * * @param svgName the name of the SVG resource (a '/'-separated path) * @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64) @@ -57,7 +60,32 @@ public class FlatSVGUtils * @see JWindow#setIconImages(List) */ public static List createWindowIconImages( String svgName ) { - SVGDiagram diagram = loadSVG( svgName ); + return createWindowIconImages( getResource( svgName ) ); + } + + /** + * Creates from the given SVG a list of icon images with different sizes that + * can be used for windows headers. The SVG should have a size of 16x16, + * otherwise it is scaled. + *

+ * If running on Windows in Java 9 or later and multi-resolution image support is available, + * then a single multi-resolution image is returned that creates images on demand + * for requested sizes from SVG. + * This has the advantage that only images for used sizes are created. + * Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG. + *

+ * This method is useful if using Java modules and the package containing the SVG + * is not opened in {@code module-info.java}. + * E.g. {@code createWindowIconImages( getClass().getResource( "/com/myapp/myicon.svg" ) )}. + * + * @param svgUrl the URL of the SVG resource + * @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64) + * @throws RuntimeException if failed to load or render SVG file + * @see JWindow#setIconImages(List) + * @since 2 + */ + public static List createWindowIconImages( URL svgUrl ) { + SVGDiagram diagram = loadSVG( svgUrl ); if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) { // use a multi-resolution image that creates images on demand for requested sizes @@ -93,6 +121,9 @@ public class FlatSVGUtils /** * Creates a buffered image and renders the given SVG into it. + *

+ * If using Java modules, the package containing the SVG must be opened in {@code module-info.java}. + * Otherwise use {@link #svg2image(URL, int, int)}. * * @param svgName the name of the SVG resource (a '/'-separated path) * @param width the width of the image @@ -101,11 +132,32 @@ public class FlatSVGUtils * @throws RuntimeException if failed to load or render SVG file */ public static BufferedImage svg2image( String svgName, int width, int height ) { - return svg2image( loadSVG( svgName ), width, height ); + return svg2image( getResource( svgName ), width, height ); } /** * Creates a buffered image and renders the given SVG into it. + *

+ * This method is useful if using Java modules and the package containing the SVG + * is not opened in {@code module-info.java}. + * E.g. {@code svg2image( getClass().getResource( "/com/myapp/myicon.svg" ), 24, 24 )}. + * + * @param svgUrl the URL of the SVG resource + * @param width the width of the image + * @param height the height of the image + * @return the image + * @throws RuntimeException if failed to load or render SVG file + * @since 2 + */ + public static BufferedImage svg2image( URL svgUrl, int width, int height ) { + return svg2image( loadSVG( svgUrl ), width, height ); + } + + /** + * Creates a buffered image and renders the given SVG into it. + *

+ * If using Java modules, the package containing the SVG must be opened in {@code module-info.java}. + * Otherwise use {@link #svg2image(URL, float)}. * * @param svgName the name of the SVG resource (a '/'-separated path) * @param scaleFactor the amount by which the SVG size is scaled @@ -113,7 +165,24 @@ public class FlatSVGUtils * @throws RuntimeException if failed to load or render SVG file */ public static BufferedImage svg2image( String svgName, float scaleFactor ) { - SVGDiagram diagram = loadSVG( svgName ); + return svg2image( getResource( svgName ), scaleFactor ); + } + + /** + * Creates a buffered image and renders the given SVG into it. + *

+ * This method is useful if using Java modules and the package containing the SVG + * is not opened in {@code module-info.java}. + * E.g. {@code svg2image( getClass().getResource( "/com/myapp/myicon.svg" ), 1.5f )}. + * + * @param svgUrl the URL of the SVG resource + * @param scaleFactor the amount by which the SVG size is scaled + * @return the image + * @throws RuntimeException if failed to load or render SVG file + * @since 2 + */ + public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) { + SVGDiagram diagram = loadSVG( svgUrl ); int width = (int) (diagram.getWidth() * scaleFactor); int height = (int) (diagram.getHeight() * scaleFactor); return svg2image( diagram, width, height ); @@ -155,16 +224,19 @@ public class FlatSVGUtils } } + private static URL getResource( String svgName ) { + return FlatSVGUtils.class.getResource( svgName ); + } + /** * Loads a SVG file. * - * @param svgName the name of the SVG resource (a '/'-separated path) + * @param url the URL of the SVG resource * @return the SVG diagram * @throws RuntimeException if failed to load SVG file */ - private static SVGDiagram loadSVG( String svgName ) { + private static SVGDiagram loadSVG( URL url ) { try { - URL url = FlatSVGUtils.class.getResource( svgName ); return SVGCache.getSVGUniverse().getDiagram( url.toURI() ); } catch( URISyntaxException ex ) { throw new RuntimeException( ex );