Java tutorial
/* * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by * applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS * OF ANY KIND, either express or implied. See the License for the specific * language governing permissions and limitations under the License. */ package net.rptools.image.listeners; import javafx.application.Platform; import javafx.geometry.Bounds; import javafx.geometry.Point2D; import javafx.scene.SnapshotParameters; import javafx.scene.image.Image; import javafx.scene.image.WritableImage; import javafx.scene.paint.Color; import javafx.scene.paint.ImagePattern; import javafx.scene.shape.Polygon; import javafx.scene.shape.StrokeLineCap; import javafx.scene.shape.StrokeLineJoin; import net.rptools.image.ImageLayerImpl; import net.rptools.image.Selection; import org.apache.commons.lang3.StringUtils; import org.rptools.framework.SystemEvent; import org.rptools.framework.ThreadPolicy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Represents the listening to draw (related) events. * @author username */ public class DrawHandler extends AbstractHandler { // Utility private static final Logger LOGGER = LoggerFactory.getLogger(DrawHandler.class); // Parameter row private static final String[] PARAMS = { "{" + START + "|continue|" + END + "}", "x", "y", "pen", "fill", "radius" }; // First index private static final int PHASE = 1; // Second index private static final int X = 2; // Third index private static final int Y = 3; // Fourth index private static final int PEN = 4; // Fifth index private static final int FILL = 5; // Sixth index private static final int RADIUS = 6; // Current Shape private Polygon currentShape; // Current pen private Image currentPen; // Current fill private Image currentFill; /** * Constructor. * @param aLayer back reference * @param aSelection selection to operate on */ public DrawHandler(final ImageLayerImpl aLayer, final Selection aSelection) { super(aLayer, aSelection); } @Override public boolean handle(final SystemEvent ev, final String[] params) { final Point2D drag = new Point2D(Double.parseDouble(params[X]), Double.parseDouble(params[Y])); Platform.runLater(new Runnable() { @Override public void run() { draw(params[PHASE], drag, params[PEN], params[FILL], Integer.parseInt(params[RADIUS])); } }); return true; } @Override public String info() { return StringUtils.join(PARAMS, ' '); } /** * Main work method. * @param phase phase of drawing we are in * @param newEnd new end of current draw * @param pen pen color * @param fill fill color * @param radius pen radius */ @ThreadPolicy(ThreadPolicy.ThreadId.JFX) private void draw(final String phase, final Point2D newEnd, final String pen, final String fill, final int radius) { LOGGER.debug("phase={}; draw={}; pen={}; fill={}; radius={}", phase, newEnd, pen, fill, radius); if (phase.equals(START)) { currentShape = new Polygon(); getLayer().getDrawable().getChildren().add(currentShape); } if (currentShape == null) { return; } currentShape.getPoints().addAll(newEnd.getX(), newEnd.getY()); switch (fill.charAt(0)) { case '#': currentShape.setFill(Color.web(fill)); break; case '-': currentShape.setFill(null); break; default: if (currentFill == null) { currentFill = getLayer().loadImage(fill); } currentShape.setFill( new ImagePattern(currentFill, 0, 0, currentFill.getWidth(), currentFill.getHeight(), false)); } switch (pen.charAt(0)) { case '#': currentShape.setStroke(Color.web(pen)); break; case '-': currentShape.setStroke(null); break; default: if (currentPen == null) { currentPen = getLayer().loadImage(pen); } currentShape.setStroke( new ImagePattern(currentPen, 0, 0, currentPen.getWidth(), currentPen.getHeight(), false)); } currentShape.setStrokeLineCap(StrokeLineCap.ROUND); currentShape.setStrokeLineJoin(StrokeLineJoin.ROUND); currentShape.setStrokeWidth(radius); if (phase.equals(END)) { finalizeDrawing(); currentShape = null; currentPen = null; currentFill = null; } LOGGER.debug("draw polygon completed={}", currentShape == null); } /** * Convert the shape into an image for storage in the layer model. */ @ThreadPolicy(ThreadPolicy.ThreadId.JFX) private void finalizeDrawing() { final SnapshotParameters params = new SnapshotParameters(); params.setFill(Color.TRANSPARENT); final WritableImage snapshot = currentShape.snapshot(params, null); final Bounds bounds = currentShape.getBoundsInParent(); getLayer().addImage(snapshot, bounds.getMinX(), bounds.getMinY()); getLayer().getDrawable().getChildren().remove(currentShape); } }