Implement SVG export
This commit is contained in:
@@ -15,7 +15,6 @@ import ovh.gasser.newshapes.ui.listeners.SelectionListener;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.Optional;
|
||||
|
||||
public class App {
|
||||
private final static Logger logger = LoggerFactory.getLogger(App.class);
|
||||
@@ -82,6 +81,7 @@ public class App {
|
||||
JMenuItem addRectItem = new JMenuItem("Add SRectangle");
|
||||
JMenuItem addCircleItem = new JMenuItem("Add SCircle");
|
||||
JMenuItem htmlExportItem = new JMenuItem("Export to HTML");
|
||||
JMenuItem svgExportItem = new JMenuItem("Export to SVG");
|
||||
JMenuItem exitItem = new JMenuItem("Exit");
|
||||
addRectItem.addActionListener(new MenuAddListener("SRectangle", model, sview));
|
||||
addCircleItem.addActionListener(new MenuAddListener("SCircle", model, sview));
|
||||
@@ -92,11 +92,19 @@ public class App {
|
||||
logger.error("Could not export as html: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
svgExportItem.addActionListener(evt -> {
|
||||
try {
|
||||
new SVGExporter(model).export();
|
||||
} catch (FileNotFoundException e) {
|
||||
logger.error("Could not export as html: {}", e.getMessage());
|
||||
}
|
||||
});
|
||||
exitItem.addActionListener(evt -> System.exit(0));
|
||||
menuFile.add(addRectItem);
|
||||
menuFile.add(addCircleItem);
|
||||
menuFile.addSeparator();
|
||||
menuFile.add(htmlExportItem);
|
||||
menuFile.add(svgExportItem);
|
||||
menuFile.add(exitItem);
|
||||
return menuFile;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package ovh.gasser.newshapes;
|
||||
|
||||
import ovh.gasser.newshapes.shapes.SCollection;
|
||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
||||
import ovh.gasser.newshapes.ui.html.*;
|
||||
import ovh.gasser.newshapes.ui.visitors.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -12,7 +12,7 @@ public class HTMLExporter {
|
||||
|
||||
private final SCollection model;
|
||||
|
||||
private HTMLExporter() throws FileNotFoundException {
|
||||
private HTMLExporter() {
|
||||
this(SCollection.of(
|
||||
SRectangle.create(10, 10, 40, 60, Color.RED),
|
||||
SRectangle.create(70, 10, 40, 60),
|
||||
|
||||
36
src/main/java/ovh/gasser/newshapes/SVGExporter.java
Normal file
36
src/main/java/ovh/gasser/newshapes/SVGExporter.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package ovh.gasser.newshapes;
|
||||
|
||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||
import ovh.gasser.newshapes.shapes.SCircle;
|
||||
import ovh.gasser.newshapes.shapes.SCollection;
|
||||
import ovh.gasser.newshapes.ui.visitors.SVGDraftman;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class SVGExporter {
|
||||
|
||||
private final SCollection model;
|
||||
|
||||
public SVGExporter() {
|
||||
SCircle circle = SCircle.create(200, 100, 50);
|
||||
circle.addAttributes(new ColorAttributes(true, true, Color.LIGHT_GRAY, Color.BLACK));
|
||||
this.model = SCollection.of(circle);
|
||||
}
|
||||
|
||||
public SVGExporter(SCollection model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void export() throws FileNotFoundException {
|
||||
try (final PrintWriter svg = new PrintWriter("out.svg")) {
|
||||
SVGDraftman draftman = new SVGDraftman(svg);
|
||||
draftman.generateSVG(this.model);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException {
|
||||
new SVGExporter().export();
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package ovh.gasser.newshapes.ui.html;
|
||||
package ovh.gasser.newshapes.ui.visitors;
|
||||
|
||||
import ovh.gasser.newshapes.ShapeVisitor;
|
||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||
@@ -0,0 +1,82 @@
|
||||
package ovh.gasser.newshapes.ui.visitors;
|
||||
|
||||
import ovh.gasser.newshapes.App;
|
||||
import ovh.gasser.newshapes.ShapeVisitor;
|
||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
||||
import ovh.gasser.newshapes.shapes.SCircle;
|
||||
import ovh.gasser.newshapes.shapes.SCollection;
|
||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class SVGDraftman implements ShapeVisitor {
|
||||
private static final String SVG_PRELUDE = """
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="%s" height="%s">
|
||||
""";
|
||||
private static final String SVG_POSTLUDE = "</svg>";
|
||||
|
||||
private final PrintWriter output;
|
||||
|
||||
public SVGDraftman(PrintWriter output) {
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRectangle(SRectangle sRectangle) {
|
||||
int x = sRectangle.getBounds().x;
|
||||
int y = sRectangle.getBounds().y;
|
||||
int w = sRectangle.getBounds().width;
|
||||
int h = sRectangle.getBounds().height;
|
||||
ColorAttributes attrs = (ColorAttributes) sRectangle.getAttributes(ColorAttributes.ID);
|
||||
this.output.println(String.format("""
|
||||
<rect width="%d" height="%d" x="%d" y="%d" %s />""",
|
||||
w, h, x, y, buildColorParameters(attrs)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCollection(SCollection collection) {
|
||||
collection.stream().forEach(shape -> shape.accept(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitCircle(SCircle sCircle) {
|
||||
int r = sCircle.getRadius();
|
||||
int x = sCircle.getBounds().x + r;
|
||||
int y = sCircle.getBounds().y + r;
|
||||
var attrs = (ColorAttributes) sCircle.getAttributes(ColorAttributes.ID);
|
||||
this.output.println(String.format("""
|
||||
<circle cx="%d" cy="%d" r="%d" %s />""",
|
||||
x, y, r, buildColorParameters(attrs)));
|
||||
}
|
||||
|
||||
public void generateSVG(SCollection model) {
|
||||
output.println(String.format(SVG_PRELUDE, App.WIN_SIZE.width, App.WIN_SIZE.height));
|
||||
visitCollection(model);
|
||||
output.println(SVG_POSTLUDE);
|
||||
}
|
||||
|
||||
private String colorToHex(Color c) {
|
||||
int r = c.getRed();
|
||||
int g = c.getGreen();
|
||||
int b = c.getBlue();
|
||||
return String.format("#%02x%02x%02x", r, g, b);
|
||||
}
|
||||
|
||||
private StringBuilder buildColorParameters(ColorAttributes attrs){
|
||||
var params = new StringBuilder();
|
||||
if (attrs.stroked) {
|
||||
params.append(String.format("stroke=\"%s\" stroke-width=\"1\"", colorToHex(attrs.strokedColor)));
|
||||
params.append(" ");
|
||||
}
|
||||
if (attrs.filled) {
|
||||
params.append(String.format("fill=\"%s\"", colorToHex(attrs.filledColor)));
|
||||
params.append(" ");
|
||||
} else {
|
||||
params.append(String.format("fill=\"%s\"", "none"));
|
||||
params.append(" ");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user