Sandy
Sandy

Reputation: 129

Display SVG file

Can someone suggest me a library for svg for java or some code example for displaying svg files? I'm a noob so help please.

Upvotes: 5

Views: 9549

Answers (2)

creme332
creme332

Reputation: 1935

Times have changed and there are now better alternatives to Apache Batik, depending on your use case.

If you only need to display an SVG image in a component or use an SVG file as an icon for a component, JSVG or SVGSalamander is the way to go.

Libraries

JSVG

  • Small and fast: Generally uses ~50% less memory than svgSalamander and ~98% less than Batik.
  • Under active development. Latest release v1.5.0 was in June 2024.
  • Does not yet support all features of the SVG specification, some of which it will not support at all. The list of supported features is available here.
  • Animations are not currently implemented but are planned to be supported.

SVGSalamander

  • A much smaller code foot print than Batik, and only one JAR file to include.
  • Easy rendering to any Graphics2D or BufferedImage. Unlike Batik, the SVG Salamander engine does not own the graphics context, so you can pass it whatever graphics context you like.
  • SVGIcon class greatly simplifies loading and drawing images to screen
  • The project has been in maintenance only mode for some time. Latest release (v.1.1.4) was in October 2022.

Apache Batik

  • Can be used to generate, manipulate and transcode SVG images in your applications.
  • Latest release (v1.17) was in August 2023.

JSVG examples

SVG as image

To display an SVG image in a Swing component:

import javax.swing.*;
import java.awt.*;
import java.net.URL;

import com.github.weisj.jsvg.*;
import com.github.weisj.jsvg.attributes.*;
import com.github.weisj.jsvg.parser.*;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public class RenderExample {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            SVGLoader loader = new SVGLoader();

            URL svgUrl = RenderExample.class.getResource("path/to/image.svg");
            SVGDocument document = loader.load(Objects.requireNonNull(svgUrl, "SVG file not found"));

            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            frame.setPreferredSize(new Dimension(400, 400));
            frame.setContentPane(new SVGPanel(Objects.requireNonNull(document)));
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }

    static class SVGPanel extends JPanel {
        private @NotNull final SVGDocument document;

        SVGPanel(@NotNull SVGDocument document) {
            this.document = document;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            ((Graphics2D) g).setRenderingHint(
                RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
            ((Graphics2D) g).setRenderingHint(
                RenderingHints.KEY_STROKE_CONTROL,
                RenderingHints.VALUE_STROKE_PURE);

            document.render(this, (Graphics2D) g, new ViewBox(0, 0, getWidth(), getHeight()));
        }
    }
}

SVG as icon

If you want to use an SVG file as the icon of a component (such as JLabel), you will have to first define your own icon class:

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;

import javax.swing.Icon;

import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.attributes.ViewBox;

public class SVGIcon implements Icon {
    private final SVGDocument document;
    private final int width;
    private final int height;

    public SVGIcon(SVGDocument document, int width, int height) {
        this.document = document;
        this.width = width;
        this.height = height;
    }

    @Override
    public void paintIcon(Component c, Graphics g, int x, int y) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        document.render(c, g2d, new ViewBox(x, y, width, height));
    }

    @Override
    public int getIconWidth() {
        return width;
    }

    @Override
    public int getIconHeight() {
        return height;
    }
}

Then to create the icon:

SVGLoader loader = new SVGLoader();
SVGDocument svgDocument = loader.load(YourClassName.class.getResource(path));
int width = 50;
int height = 50;
Icon icon =  new SVGIcon(svgDocument, width, height);

Upvotes: 1

Pau Giner
Pau Giner

Reputation: 1300

You can use Apache Batik. I downloaded it time ago and it had some examples on displaying SVG. For displaying SVG in a Swing component you can follow this example.

Upvotes: 13

Related Questions