Implement SVG export
This commit is contained in:
@@ -15,7 +15,6 @@ import ovh.gasser.newshapes.ui.listeners.SelectionListener;
|
|||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class App {
|
public class App {
|
||||||
private final static Logger logger = LoggerFactory.getLogger(App.class);
|
private final static Logger logger = LoggerFactory.getLogger(App.class);
|
||||||
@@ -82,6 +81,7 @@ public class App {
|
|||||||
JMenuItem addRectItem = new JMenuItem("Add SRectangle");
|
JMenuItem addRectItem = new JMenuItem("Add SRectangle");
|
||||||
JMenuItem addCircleItem = new JMenuItem("Add SCircle");
|
JMenuItem addCircleItem = new JMenuItem("Add SCircle");
|
||||||
JMenuItem htmlExportItem = new JMenuItem("Export to HTML");
|
JMenuItem htmlExportItem = new JMenuItem("Export to HTML");
|
||||||
|
JMenuItem svgExportItem = new JMenuItem("Export to SVG");
|
||||||
JMenuItem exitItem = new JMenuItem("Exit");
|
JMenuItem exitItem = new JMenuItem("Exit");
|
||||||
addRectItem.addActionListener(new MenuAddListener("SRectangle", model, sview));
|
addRectItem.addActionListener(new MenuAddListener("SRectangle", model, sview));
|
||||||
addCircleItem.addActionListener(new MenuAddListener("SCircle", 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());
|
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));
|
exitItem.addActionListener(evt -> System.exit(0));
|
||||||
menuFile.add(addRectItem);
|
menuFile.add(addRectItem);
|
||||||
menuFile.add(addCircleItem);
|
menuFile.add(addCircleItem);
|
||||||
menuFile.addSeparator();
|
menuFile.addSeparator();
|
||||||
menuFile.add(htmlExportItem);
|
menuFile.add(htmlExportItem);
|
||||||
|
menuFile.add(svgExportItem);
|
||||||
menuFile.add(exitItem);
|
menuFile.add(exitItem);
|
||||||
return menuFile;
|
return menuFile;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package ovh.gasser.newshapes;
|
|||||||
|
|
||||||
import ovh.gasser.newshapes.shapes.SCollection;
|
import ovh.gasser.newshapes.shapes.SCollection;
|
||||||
import ovh.gasser.newshapes.shapes.SRectangle;
|
import ovh.gasser.newshapes.shapes.SRectangle;
|
||||||
import ovh.gasser.newshapes.ui.html.*;
|
import ovh.gasser.newshapes.ui.visitors.*;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
@@ -12,7 +12,7 @@ public class HTMLExporter {
|
|||||||
|
|
||||||
private final SCollection model;
|
private final SCollection model;
|
||||||
|
|
||||||
private HTMLExporter() throws FileNotFoundException {
|
private HTMLExporter() {
|
||||||
this(SCollection.of(
|
this(SCollection.of(
|
||||||
SRectangle.create(10, 10, 40, 60, Color.RED),
|
SRectangle.create(10, 10, 40, 60, Color.RED),
|
||||||
SRectangle.create(70, 10, 40, 60),
|
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.ShapeVisitor;
|
||||||
import ovh.gasser.newshapes.attributes.ColorAttributes;
|
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