blob: 969972643636b4e4f41301b1692a89cd8c82056c [file] [log] [blame]
/*
* Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package org.jdesktop.swingx.designer;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
/**
* PathShape
*
* @author Created by Jasper Potts (May 29, 2007)
*/
public class PathShape extends PaintedShape {
private Shape cachedShape = null;
private List<BezierControlPoint> controlPoints = new ArrayList<BezierControlPoint>();
private PropertyChangeListener cpListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
rebuildShape();
}
};
// =================================================================================================================
// Constructors
/** private noargs constructor for JIBX */
private PathShape() {
this(null);
}
public PathShape(UIDefaults canvasUiDefaults) {
super(canvasUiDefaults);
}
public BezierControlPoint addPoint(double x, double y) {
BezierControlPoint cp = new BezierControlPoint(x, y);
controlPoints.add(cp);
cp.addPropertyChangeListener(cpListener);
// update shape
rebuildShape();
// return new control point
return cp;
}
public Shape getShape() {
if (cachedShape == null) {
rebuildShape();
}
return cachedShape;
}
private void rebuildShape() {
GeneralPath path = new GeneralPath();
BezierControlPoint first, last;
first = last = controlPoints.get(0);
path.moveTo((float) first.getX(), (float) first.getY());
for (int i = 0; i < controlPoints.size(); i++) {
BezierControlPoint controlPoint = controlPoints.get(i);
if (last.getCp2().isSharp() && controlPoint.getCp1().isSharp()) {
path.lineTo(controlPoint.getX(), controlPoint.getY());
} else {
path.curveTo(
(float) last.getCp2().getX(), (float) last.getCp2().getY(),
(float) controlPoint.getCp1().getX(), (float) controlPoint.getCp1().getY(),
(float) controlPoint.getX(), (float) controlPoint.getY()
);
}
last = controlPoint;
}
// close path
if (last.getCp2().isSharp() && first.getCp1().isSharp()) {
path.lineTo(first.getX(), first.getY());
} else {
path.curveTo(
(float) last.getCp2().getX(), (float) last.getCp2().getY(),
(float) first.getCp1().getX(), (float) first.getCp1().getY(),
(float) first.getX(), (float) first.getY()
);
}
path.closePath();
// fire change
cachedShape = path;
firePropertyChange("shape", null, cachedShape);
}
@Override
public String toString() {
String p = "PATH {\n";
BezierControlPoint first, last;
first = last = controlPoints.get(0);
p += " path.moveTo(" + first.getX() + "," + first.getY() + ");";
for (int i = 0; i < controlPoints.size(); i++) {
BezierControlPoint controlPoint = controlPoints.get(i);
p += " path.curveTo(" +
(float) last.getCp2().getX() + "," + (float) last.getCp2().getY() + "," +
(float) controlPoint.getCp1().getX() + "," + (float) controlPoint.getCp1().getY() + "," +
(float) controlPoint.getX() + "," + (float) controlPoint.getY() +
");\n";
last = controlPoint;
}
// close path
p += " path.curveTo(" +
(float) last.getCp2().getX() + "," + (float) last.getCp2().getY() + "," +
(float) first.getCp1().getX() + "," + (float) first.getCp1().getY() + "," +
(float) first.getX() + "," + (float) first.getY() +
");\n";
p += "}\n";
return p;
}
// =================================================================================================================
// Shape Methods
public Rectangle2D getBounds(double pixelSize) {
return getShape().getBounds2D();
}
public List<? extends ControlPoint> getControlPoints() {
List<ControlPoint> pts = new ArrayList<ControlPoint>();
for (BezierControlPoint controlPoint : controlPoints) {
pts.add(controlPoint);
}
for (ControlPoint controlPoint : super.getControlPoints()) {
pts.add(controlPoint);
}
return pts;
}
public void setControlPoints(List<BezierControlPoint> controlPoints) {
List<BezierControlPoint> old = this.controlPoints;
for (BezierControlPoint cp : old) {
cp.removePropertyChangeListener(cpListener);
}
this.controlPoints = controlPoints;
for (BezierControlPoint cp : this.controlPoints) {
cp.addPropertyChangeListener(cpListener);
}
// update shape
rebuildShape();
}
public boolean isHit(Point2D p, double pixelSize) {
return getShape().contains(p);
}
public void paint(Graphics2D g2, double pixelSize) {
g2.setPaint(getPaint());
g2.fill(getShape());
}
public void paintControls(Graphics2D g2, double pixelSize, boolean paintControlLines) {
if (paintControlLines) {
g2.setStroke(new BasicStroke((float) pixelSize));
g2.setColor(GraphicsHelper.CONTROL_LINE);
g2.draw(getShape());
}
for (BezierControlPoint controlPoint : controlPoints) {
if (!controlPoint.isSharpCorner()) controlPoint.paintControls(g2, pixelSize, true);
}
}
public List<BezierControlPoint> getBezierControlPoints() {
return controlPoints;
}
}