net.rptools.image.listeners.DrawHandler.java Source code

Java tutorial

Introduction

Here is the source code for net.rptools.image.listeners.DrawHandler.java

Source

/*
 * 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);
    }
}