/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.swing.figure.interactions; import com.bc.ceres.swing.figure.FigureEditor; import com.bc.ceres.swing.figure.FigureEditorInteractor; import com.bc.ceres.swing.figure.FigureFactory; import com.bc.ceres.swing.figure.ShapeFigure; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.List; public class InsertMultiPointFigureInteractor extends FigureEditorInteractor { private final List<Point2D> points; private final boolean polygonal; private ShapeFigure figure; private boolean started; public InsertMultiPointFigureInteractor(boolean polygonal) { this.polygonal = polygonal; this.points = new ArrayList<Point2D>(8); } public boolean isPolygonal() { return polygonal; } @Override public void cancelInteraction(InputEvent event) { started = false; if (!points.isEmpty()) { points.remove(points.size() - 1); points.remove(points.size() - 1); if (points.isEmpty()) { getFigureEditor(event).getFigureCollection().removeFigure(figure); figure = null; } else { figure.setShape(createPath()); } super.cancelInteraction(event); } } @Override protected void stopInteraction(InputEvent inputEvent) { super.stopInteraction(inputEvent); started = false; } @Override public void mouseClicked(MouseEvent event) { if (started) { if (event.getClickCount() > 1) { if (points.isEmpty()) { getFigureEditor(event).getFigureCollection().removeFigure(figure); figure = null; } else { FigureEditor figureEditor = getFigureEditor(event); figureEditor.getFigureSelection().removeAllFigures(); if (isPolygonal()) { removeNotNeededPoints(); } figure.setShape(createPath()); points.clear(); figureEditor.insertFigures(false, figure); stopInteraction(event); } } } } private void removeNotNeededPoints() { final int moreThanFour = points.size() - 4; int i = Math.min(2, moreThanFour); while (i > 0) { points.remove(0); // remove additional points inserted for JTS polygon i--; } points.remove(points.size() - 1); // remove last temporary point } @Override public void mouseReleased(MouseEvent event) { if (!started) { started = startInteraction(event); } if (!started) { return; } final FigureEditor figureEditor = getFigureEditor(event); boolean startingNewFigure = false; if (points.isEmpty()) { figureEditor.getFigureSelection().removeAllFigures(); startingNewFigure = true; } if (!startingNewFigure) { points.remove(points.size() - 1); // remove last temporary point } points.add(toModelPoint(event)); points.add(toModelPoint(event)); if (isPolygonal() && startingNewFigure) { // insert 2 additional points for JTS polygon points.add(toModelPoint(event)); points.add(toModelPoint(event)); } if (startingNewFigure) { FigureFactory factory = figureEditor.getFigureFactory(); if (isPolygonal()) { figure = factory.createPolygonFigure(createPath(), figureEditor.getDefaultPolygonStyle()); } else { figure = factory.createLineFigure(createPath(), figureEditor.getDefaultLineStyle()); } figureEditor.getFigureCollection().addFigure(figure); } } @Override public void mouseMoved(MouseEvent event) { if (started) { if (!points.isEmpty()) { points.set(points.size() - 1, toModelPoint(event)); figure.setShape(createPath()); } } } protected Path2D createPath() { Point2D[] points = getPoints(); Path2D.Double path = new Path2D.Double(); path.moveTo(points[0].getX(), points[0].getY()); for (int i = 1; i < points.length; i++) { path.lineTo(points[i].getX(), points[i].getY()); } if (isPolygonal()) { path.closePath(); } return path; } protected Point2D[] getPoints() { return points.toArray(new Point2D[points.size()]); } }