Umsetzung von issue #7

Die Anker werden nun als Options.Direction Typ gespeichert und nicht mehr als konkreter Point2D. Die Ankerpunkte werden dann beim Zeichnen dynamisch berechnet. Dies ist intuitiver für die Benutzung von Ankern, da ein Anker, der auf CENTER gesetzt wurde auch nach Skalierung und Änderungen der Größe im Mittelpunkt der Form bleibt. Dies ist vor allem für die Ausrichtung von Texten hilfreich.
This commit is contained in:
ngb
2022-01-06 09:02:24 +01:00
parent 3f945bc72d
commit 458d22aa24
17 changed files with 305 additions and 195 deletions

View File

@@ -98,11 +98,6 @@ public class Arc extends Shape {
} }
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, height, anchor);
}
@Override @Override
public java.awt.Shape getShape() { public java.awt.Shape getShape() {
return new Arc2D.Double(0, 0, width, height, startingangle, angle, type.awt_type); return new Arc2D.Double(0, 0, width, height, startingangle, angle, type.awt_type);

View File

@@ -1,5 +1,6 @@
package schule.ngb.zm.shapes; package schule.ngb.zm.shapes;
import org.jetbrains.annotations.NotNull;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import schule.ngb.zm.Vector; import schule.ngb.zm.Vector;
@@ -29,7 +30,7 @@ public class Arrow extends Line {
* *
* @param vector * @param vector
*/ */
public Arrow( Vector vector ) { public Arrow( @NotNull Vector vector ) {
this(0, 0, vector.x, vector.y); this(0, 0, vector.x, vector.y);
} }
@@ -40,7 +41,7 @@ public class Arrow extends Line {
* @param vector1 * @param vector1
* @param vector2 * @param vector2
*/ */
public Arrow( Vector vector1, Vector vector2 ) { public Arrow( @NotNull Vector vector1, @NotNull Vector vector2 ) {
this(vector1.x, vector1.y, vector2.x, vector2.y); this(vector1.x, vector1.y, vector2.x, vector2.y);
} }
@@ -52,7 +53,7 @@ public class Arrow extends Line {
* @param y * @param y
* @param vector * @param vector
*/ */
public Arrow( double x, double y, Vector vector ) { public Arrow( double x, double y, @NotNull Vector vector ) {
this(x, y, x + vector.x, y + vector.y); this(x, y, x + vector.x, y + vector.y);
} }
@@ -61,7 +62,7 @@ public class Arrow extends Line {
* *
* @param line * @param line
*/ */
public Arrow( Line line ) { public Arrow( @NotNull Line line ) {
this(line.x, line.y, line.x2, line.y2); this(line.x, line.y, line.x2, line.y2);
this.copyFrom(line); this.copyFrom(line);
} }
@@ -150,16 +151,16 @@ public class Arrow extends Line {
} }
@Override @Override
public void draw( Graphics2D graphics, AffineTransform at ) { public void draw( Graphics2D graphics, AffineTransform transform ) {
if( !visible ) { if( !visible ) {
return; return;
} }
super.draw(graphics, at); super.draw(graphics, transform);
java.awt.Shape head = getHeadShape(); java.awt.Shape head = getHeadShape();
if( at != null ) { if( transform != null ) {
head = at.createTransformedShape(head); head = transform.createTransformedShape(head);
} }
Color currentColor = graphics.getColor(); Color currentColor = graphics.getColor();

View File

@@ -0,0 +1,30 @@
package schule.ngb.zm.shapes;
import java.awt.geom.Rectangle2D;
public class Bounds extends Rectangle2D.Double {
public Bounds( double x, double y, double w, double h ) {
super(x,y,w,h);
}
public Bounds( Shape shape ) {
if( shape != null ) {
java.awt.Shape s = shape.getShape();
if( s != null ) {
s = shape.getTransform().createTransformedShape(s);
Rectangle2D bounds = s.getBounds2D();
x = bounds.getX();
y = bounds.getY();
width = bounds.getWidth();
height = bounds.getHeight();
} else {
x = shape.getX();
y = shape.getY();
width = 0;
height = 0;
}
}
}
}

View File

@@ -11,7 +11,6 @@ public class Circle extends Shape {
public Circle( double x, double y, double radius ) { public Circle( double x, double y, double radius ) {
super(x, y); super(x, y);
this.radius = radius; this.radius = radius;
setAnchor(CENTER);
} }
public Circle( Circle circle ) { public Circle( Circle circle ) {
@@ -19,6 +18,16 @@ public class Circle extends Shape {
copyFrom(circle); copyFrom(circle);
} }
@Override
public double getWidth() {
return radius+radius;
}
@Override
public double getHeight() {
return radius+radius;
}
public double getRadius() { public double getRadius() {
return radius; return radius;
} }
@@ -51,11 +60,6 @@ public class Circle extends Shape {
return new Ellipse2D.Double(0, 0, radius + radius, radius + radius); return new Ellipse2D.Double(0, 0, radius + radius, radius + radius);
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(radius + radius, radius + radius, anchor);
}
@Override @Override
public boolean equals( Object o ) { public boolean equals( Object o ) {
if( this == o ) return true; if( this == o ) return true;

View File

@@ -34,6 +34,16 @@ public class Curve extends Shape {
coordinates = Arrays.copyOf(curve.coordinates, curve.coordinates.length); coordinates = Arrays.copyOf(curve.coordinates, curve.coordinates.length);
} }
@Override
public double getWidth() {
return Math.abs(x-coordinates[coordinates.length-2]);
}
@Override
public double getHeight() {
return Math.abs(y-coordinates[coordinates.length-1]);
}
public Point2D getStart() { public Point2D getStart() {
return new Point2D.Double(x, y); return new Point2D.Double(x, y);
} }
@@ -136,6 +146,9 @@ public class Curve extends Shape {
@Override @Override
public void scale( double factor ) { public void scale( double factor ) {
super.scale(factor); super.scale(factor);
/*for( int i = 0; i < coordinates.length; i++ ) {
coordinates[i] *= factor;
}*/
coordinates[coordinates.length - 4] *= factor; coordinates[coordinates.length - 4] *= factor;
coordinates[coordinates.length - 3] *= factor; coordinates[coordinates.length - 3] *= factor;
coordinates[coordinates.length - 2] *= factor; coordinates[coordinates.length - 2] *= factor;

View File

@@ -1,31 +1,55 @@
package schule.ngb.zm.shapes; package schule.ngb.zm.shapes;
import org.jetbrains.annotations.NotNull;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
public class CustomShape extends Shape { public class CustomShape extends Shape {
protected Path2D.Double path; protected Path2D.Double path;
private double width = 0.0, height = 0.0;
public CustomShape( double x, double y ) { public CustomShape( double x, double y ) {
super(x, y); super(x, y);
path = new Path2D.Double(); path = new Path2D.Double();
} }
public CustomShape( CustomShape custom ) { public CustomShape( @NotNull CustomShape custom ) {
super(custom.x, custom.y); super(custom.x, custom.y);
path = custom.path; path = custom.path;
calculateBounds();
}
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
private void calculateBounds() {
java.awt.Rectangle s = path.getBounds();
width = s.width;
height = s.height;
} }
public void lineTo( double x, double y ) { public void lineTo( double x, double y ) {
path.lineTo(x - x, y - y); path.lineTo(x - x, y - y);
calculateBounds();
} }
public void arcTo( double x1, double y1, double x2, double y2 ) { public void arcTo( double x1, double y1, double x2, double y2 ) {
path.quadTo(x1 - x, y1 - y, x2 - x, y2 - y); path.quadTo(x1 - x, y1 - y, x2 - x, y2 - y);
calculateBounds();
} }
public void curveTo( double x1, double y1, double x2, double y2, double x3, double y3 ) { public void curveTo( double x1, double y1, double x2, double y2, double x3, double y3 ) {
path.curveTo(x1 - x, y1 - y, x2 - x, y2 - y, x3 - x, y3 - y); path.curveTo(x1 - x, y1 - y, x2 - x, y2 - y, x3 - x, y3 - y);
calculateBounds();
} }
public void close() { public void close() {

View File

@@ -14,7 +14,7 @@ public class Ellipse extends Shape {
super(x, y); super(x, y);
this.width = width; this.width = width;
this.height = height; this.height = height;
setAnchor(CENTER); this.anchor = Options.Direction.CENTER;
} }
public Ellipse( Ellipse ellipse ) { public Ellipse( Ellipse ellipse ) {
@@ -22,18 +22,20 @@ public class Ellipse extends Shape {
copyFrom(ellipse); copyFrom(ellipse);
} }
@Override
public double getWidth() { public double getWidth() {
return width; return width;
} }
public void setWidth( double width ) { @Override
this.width = width;
}
public double getHeight() { public double getHeight() {
return height; return height;
} }
public void setWidth( double width ) {
this.width = width;
}
public void setHeight( double height ) { public void setHeight( double height ) {
this.height = height; this.height = height;
} }
@@ -60,11 +62,6 @@ public class Ellipse extends Shape {
height *= factor; height *= factor;
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, height, anchor);
}
@Override @Override
public java.awt.Shape getShape() { public java.awt.Shape getShape() {
return new Ellipse2D.Double(0, 0, width, height); return new Ellipse2D.Double(0, 0, width, height);

View File

@@ -21,7 +21,7 @@ public class Kite extends Shape {
this.width = width; this.width = width;
this.height = height; this.height = height;
this.ratio = ratio; this.ratio = ratio;
setAnchor(CENTER); this.anchor = Options.Direction.CENTER;
} }
public Kite( Kite pKite ) { public Kite( Kite pKite ) {
@@ -29,6 +29,7 @@ public class Kite extends Shape {
copyFrom(pKite); copyFrom(pKite);
} }
@Override
public double getWidth() { public double getWidth() {
return width; return width;
} }
@@ -37,6 +38,7 @@ public class Kite extends Shape {
this.width = width; this.width = width;
} }
@Override
public double getHeight() { public double getHeight() {
return height; return height;
} }
@@ -76,11 +78,6 @@ public class Kite extends Shape {
height *= factor; height *= factor;
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, height, anchor);
}
@Override @Override
public java.awt.Shape getShape() { public java.awt.Shape getShape() {
double hHalf = width * .5, hRatio = ratio * height; double hHalf = width * .5, hRatio = ratio * height;

View File

@@ -1,5 +1,6 @@
package schule.ngb.zm.shapes; package schule.ngb.zm.shapes;
import org.jetbrains.annotations.NotNull;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import java.awt.geom.Line2D; import java.awt.geom.Line2D;
@@ -16,7 +17,7 @@ public class Line extends Shape {
this.y2 = y2; this.y2 = y2;
} }
public Line( Line line ) { public Line( @NotNull Line line ) {
this(line.x, line.y, line.x2, line.y2); this(line.x, line.y, line.x2, line.y2);
copyFrom(line); copyFrom(line);
} }
@@ -37,6 +38,21 @@ public class Line extends Shape {
this.y2 = y; this.y2 = y;
} }
@Override
public double getWidth() {
return Math.abs(x2-x);
}
@Override
public double getHeight() {
return Math.abs(y2-y);
}
@Override
public Bounds getBounds() {
return new Bounds(Math.min(x,x2), Math.min(y,y2), getWidth(), getHeight());
}
@Override @Override
public void scale( double factor ) { public void scale( double factor ) {
super.scale(factor); super.scale(factor);
@@ -75,11 +91,6 @@ public class Line extends Shape {
y2 += dy; y2 += dy;
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(x2 - x, y2 - y, anchor);
}
@Override @Override
public java.awt.Shape getShape() { public java.awt.Shape getShape() {
return new Line2D.Double(0, 0, x2 - x, y2 - y); return new Line2D.Double(0, 0, x2 - x, y2 - y);

View File

@@ -35,7 +35,7 @@ public class Picture extends Shape {
width = image.getWidth(); width = image.getWidth();
height = image.getHeight(); height = image.getHeight();
setAnchor(CENTER); this.anchor = Options.Direction.CENTER;
} }
public Picture( Picture picture ) { public Picture( Picture picture ) {
@@ -60,7 +60,6 @@ public class Picture extends Shape {
width = image.getWidth(); width = image.getWidth();
height = image.getHeight(); height = image.getHeight();
setAnchor(shape.getAnchor());
} }
} }
@@ -69,7 +68,7 @@ public class Picture extends Shape {
} }
public void setWidth( double width ) { public void setWidth( double width ) {
scale(width / width); scale(width / this.width);
} }
public double getHeight() { public double getHeight() {
@@ -77,18 +76,13 @@ public class Picture extends Shape {
} }
public void setHeight( double height ) { public void setHeight( double height ) {
scale(height / height); scale(height / this.height);
} }
public BufferedImage getImage() { public BufferedImage getImage() {
return image; return image;
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, height, anchor);
}
@Override @Override
public void scale( double factor ) { public void scale( double factor ) {
super.scale(factor); super.scale(factor);
@@ -114,7 +108,7 @@ public class Picture extends Shape {
*/ */
@Override @Override
public void draw( Graphics2D graphics, AffineTransform pVerzerrung ) { public void draw( Graphics2D graphics, AffineTransform transform ) {
if( !visible ) { if( !visible ) {
return; return;
} }

View File

@@ -20,7 +20,7 @@ public class Point extends Circle {
/** /**
* Erstellt ein Punktobjekt mit den Koordinaten des übergebenen * Erstellt ein Punktobjekt mit den Koordinaten des übergebenen
* {@link schule.ngb.zm.Vector Vektors}. * {@link schule.ngb.zm.Vector Vektors}.
* @param point * @param vector
*/ */
public Point( schule.ngb.zm.Vector vector ) { public Point( schule.ngb.zm.Vector vector ) {
super(vector.x, vector.y, POINT_RADIUS); super(vector.x, vector.y, POINT_RADIUS);
@@ -52,7 +52,7 @@ public class Point extends Circle {
@Override @Override
public void setAnchor( Options.Direction anchor ) { public void setAnchor( Options.Direction anchor ) {
// Punkte sind immer im Zentrum verankert // Punkte sind immer im Zentrum verankert
calculateAnchor(radius + radius, radius + radius, CENTER); super.setAnchor(Options.Direction.CENTER);
} }
} }

View File

@@ -7,6 +7,8 @@ public class Polygon extends Shape {
protected Point2D[] points; protected Point2D[] points;
private double width = 0.0, height = 0.0;
public Polygon( double x, double y, Point2D... points ) { public Polygon( double x, double y, Point2D... points ) {
super(x, y); super(x, y);
@@ -14,6 +16,8 @@ public class Polygon extends Shape {
for( int i = 0; i < points.length; i++ ) { for( int i = 0; i < points.length; i++ ) {
this.points[i] = new Point2D.Double(points[i].getX() - x, points[i].getY() - y); this.points[i] = new Point2D.Double(points[i].getX() - x, points[i].getY() - y);
} }
calculateBounds();
} }
public Polygon( Point2D... points ) { public Polygon( Point2D... points ) {
@@ -25,6 +29,8 @@ public class Polygon extends Shape {
} }
this.points[i] = new Point2D.Double(points[i].getX() - x, points[i].getY() - y); this.points[i] = new Point2D.Double(points[i].getX() - x, points[i].getY() - y);
} }
calculateBounds();
} }
public Polygon( double x1, double y1, double x2, double y2, double... coordinates ) { public Polygon( double x1, double y1, double x2, double y2, double... coordinates ) {
@@ -38,6 +44,8 @@ public class Polygon extends Shape {
for( int i = 0; i < numPoints - 2; i += 1 ) { for( int i = 0; i < numPoints - 2; i += 1 ) {
this.points[i + 2] = new Point2D.Double(coordinates[i * 2] - x1, coordinates[i * 2 + 1] - y1); this.points[i + 2] = new Point2D.Double(coordinates[i * 2] - x1, coordinates[i * 2 + 1] - y1);
} }
calculateBounds();
} }
public Polygon( Polygon polygon ) { public Polygon( Polygon polygon ) {
@@ -45,6 +53,22 @@ public class Polygon extends Shape {
copyFrom(polygon); copyFrom(polygon);
} }
@Override
public double getWidth() {
return width;
}
@Override
public double getHeight() {
return height;
}
private void calculateBounds() {
java.awt.Rectangle s = getShape().getBounds();
width = s.width;
height = s.height;
}
public Point2D[] getPoints() { public Point2D[] getPoints() {
return points; return points;
} }
@@ -60,6 +84,7 @@ public class Polygon extends Shape {
points[i] = new Point2D.Double(v.points[i].getX(), v.points[i].getY()); points[i] = new Point2D.Double(v.points[i].getX(), v.points[i].getY());
} }
} }
calculateBounds();
} }
@Override @Override

View File

@@ -14,7 +14,7 @@ public class Rectangle extends Shape {
super(x, y); super(x, y);
this.width = width; this.width = width;
this.height = height; this.height = height;
setAnchor(NORTHWEST); this.anchor = Options.Direction.NORTHWEST;
} }
public Rectangle( Rectangle pRechteck ) { public Rectangle( Rectangle pRechteck ) {
@@ -36,23 +36,24 @@ public class Rectangle extends Shape {
strokeType = DASHED; strokeType = DASHED;
} }
@Override
public double getWidth() { public double getWidth() {
return width; return width;
} }
@Override
public double getHeight() {
return height;
}
public void setWidth( double width ) { public void setWidth( double width ) {
this.width = width; this.width = width;
} }
public double getHeight() {
return height;
}
public void setHeight( double height ) { public void setHeight( double height ) {
this.height = height; this.height = height;
} }
@Override @Override
public Rectangle copy() { public Rectangle copy() {
return new Rectangle(this); return new Rectangle(this);
@@ -80,11 +81,6 @@ public class Rectangle extends Shape {
return new Rectangle2D.Double(0, 0, width, height); return new Rectangle2D.Double(0, 0, width, height);
} }
@Override
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, height, anchor);
}
@Override @Override
public boolean equals( Object o ) { public boolean equals( Object o ) {
if( this == o ) return true; if( this == o ) return true;

View File

@@ -4,7 +4,6 @@ public class Rhombus extends Kite {
public Rhombus( double x, double y, double width, double height ) { public Rhombus( double x, double y, double width, double height ) {
super(x, y, width, height, 0.5); super(x, y, width, height, 0.5);
setAnchor(CENTER);
} }
public Rhombus( Rhombus rhombus ) { public Rhombus( Rhombus rhombus ) {

View File

@@ -3,10 +3,10 @@ package schule.ngb.zm.shapes;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import java.awt.*; import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
public abstract class Shape extends FilledShape { public abstract class Shape extends FilledShape {
@@ -20,7 +20,7 @@ public abstract class Shape extends FilledShape {
protected boolean visible = true; protected boolean visible = true;
protected Point2D.Double anchor = new Point2D.Double(); protected Options.Direction anchor = Options.Direction.CENTER;
public Shape( double x, double y ) { public Shape( double x, double y ) {
this.x = x; this.x = x;
@@ -47,6 +47,32 @@ public abstract class Shape extends FilledShape {
this.y = y; this.y = y;
} }
/**
* Gibt die Breite dieser Form zurück.
* <p>
* Die Breite einer Form ist immer die Breite ihrer Begrenzung, <b>bevor</b>
* Drehungen und andere Transformationen auf sei angewandt wurden.
* <p>
* Die Begrenzungen der tatsächlich gezeichneten Form kann mit {@link #getBounds()}
* abgerufen werden.
*
* @return
*/
public abstract double getWidth();
/**
* Gibt die Höhe dieser Form zurück.
* <p>
* Die Höhe einer Form ist immer die Höhe ihrer Begrenzung, <b>bevor</b>
* Drehungen und andere Transformationen auf sei angewandt wurden.
* <p>
* Die Begrenzungen der tatsächlich gezeichneten Form kann mit {@link #getBounds()}
* abgerufen werden.
*
* @return
*/
public abstract double getHeight();
public double getRotation() { public double getRotation() {
return rotation; return rotation;
} }
@@ -71,114 +97,84 @@ public abstract class Shape extends FilledShape {
visible = !visible; visible = !visible;
} }
public Point2D.Double getAnchor() { public Options.Direction getAnchor() {
return new Point2D.Double(anchor.x, anchor.y); return anchor;
} }
/** /**
* Setzt den Ankerpunkt der Form basierend auf der angegebenen * Setzt den Ankerpunkt der Form basierend auf der angegebenen
* {@link Options.Direction Richtung}. * {@link Options.Direction Richtung}.
* * <p>
* Für das Setzen des Ankers muss das {@link #getBounds() begrenzende * Für das Setzen des Ankers muss das {@link #getBounds() begrenzende
* Rechteck} berechnet werden. Unterklassen sollten die Methode * Rechteck} berechnet werden. Unterklassen sollten die Methode
* überschreiben, wenn der Anker auch direkt gesetzt werden kann. * überschreiben, wenn der Anker auch direkt gesetzt werden kann.
*
* @param anchor * @param anchor
*/ */
public void setAnchor( Options.Direction anchor ) { public void setAnchor( Options.Direction anchor ) {
java.awt.Shape shape = getShape();
if( shape != null ) {
Rectangle2D bounds = shape.getBounds2D();
calculateAnchor(bounds.getWidth(), bounds.getHeight(), anchor);
} else {
this.anchor.x = 0;
this.anchor.y = 0;
}
}
/**
* Setzt den Ankerpunkt explizit auf den angegebenen
* @param anchor
*/
public void setAnchor( Point2D.Double anchor ) {
setAnchor(anchor, false);
}
public void setAnchor( Point2D.Double anchor, boolean isRelative ) {
if( anchor != null ) { if( anchor != null ) {
setAnchor(anchor.x, anchor.y, isRelative); this.anchor = anchor;
} else {
setAnchor(0, 0, true);
}
}
public void setAnchor( double x, double y ) {
setAnchor(x, y, false);
}
public void setAnchor( double x, double y, boolean isRelative ) {
if( isRelative ) {
this.anchor.x = x;
this.anchor.y = y;
} else {
this.anchor.x = this.x-x;
this.anchor.y = this.y-y;
} }
} }
/** /**
* Hilfsmethode zur Berechnung eines Ankerpunktes relativ zu den angegebenen * Bestimmt den Ankerpunkt der Form relativ zur oberen linken Ecke und
* Begrenzungen basierend aus {@link #x}-, {@link #y}-Koordinate und * abhängig vom gesetzten {@link #setAnchor(Options.Direction) Anker}.
* <var>width</var> / <var>height</var> (Breite / Höhe).
* @param width
* @param height
* @param anchor
*/ */
protected void calculateAnchor( double width, double height, @NotNull Options.Direction anchor ) { public Point2D.Double getAnchorPoint() {
double bHalf = width * .5, hHalf = height * .5; Point2D.Double anchorpoint = new Point2D.Double(0, 0);
// pAnker == CENTER
this.anchor.x = bHalf; double bHalf = getWidth() * .5, hHalf = getHeight() * .5;
this.anchor.y = hHalf; // anchor == CENTER
anchorpoint.x = bHalf;
anchorpoint.y = hHalf;
if( NORTH.is(anchor) ) { if( NORTH.is(anchor) ) {
this.anchor.y -= hHalf; anchorpoint.y -= hHalf;
} }
if( SOUTH.is(anchor) ) { if( SOUTH.is(anchor) ) {
this.anchor.y += hHalf; anchorpoint.y += hHalf;
} }
if( WEST.is(anchor) ) { if( WEST.is(anchor) ) {
this.anchor.x -= bHalf; anchorpoint.x -= bHalf;
} }
if( EAST.is(anchor) ) { if( EAST.is(anchor) ) {
this.anchor.x += bHalf; anchorpoint.x += bHalf;
} }
return anchorpoint;
} }
/** /**
* Kopiert die Eigenschaften der übergebenen Form in diese. * Kopiert die Eigenschaften der übergebenen Form in diese.
* * <p>
* Unterklassen sollten diese Methode überschreiben, um weitere Eigenschaften * Unterklassen sollten diese Methode überschreiben, um weitere Eigenschaften
* zu kopieren (zum Beispiel den Radius eines Kreises). Mit dem Aufruf * zu kopieren (zum Beispiel den Radius eines Kreises). Mit dem Aufruf
* <code>super.copyFrom(shape)</code> sollten die Basiseigenschaften * <code>super.copyFrom(shape)</code> sollten die Basiseigenschaften
* kopiert werden. * kopiert werden.
*
* @param shape * @param shape
*/ */
public void copyFrom( Shape shape ) { public void copyFrom( Shape shape ) {
moveTo(shape.x, shape.y); if( shape != null ) {
setFillColor(shape.getFillColor()); moveTo(shape.x, shape.y);
setStrokeColor(shape.getStrokeColor()); setFillColor(shape.getFillColor());
setStrokeWeight(shape.getStrokeWeight()); setStrokeColor(shape.getStrokeColor());
setStrokeType(shape.getStrokeType()); setStrokeWeight(shape.getStrokeWeight());
visible = shape.isVisible(); setStrokeType(shape.getStrokeType());
rotation = shape.rotation; visible = shape.isVisible();
scale(shape.scale); rotation = shape.rotation;
setAnchor(shape.getAnchor()); scale(shape.scale);
setAnchor(shape.getAnchor());
}
} }
public abstract Shape copy(); public abstract Shape copy();
public abstract java.awt.Shape getShape(); public abstract java.awt.Shape getShape();
public Rectangle getBounds() { public Bounds getBounds() {
return new Rectangle(this); return new Bounds(this);
} }
public void move( double dx, double dy ) { public void move( double dx, double dy ) {
@@ -193,8 +189,6 @@ public abstract class Shape extends FilledShape {
public void scale( double factor ) { public void scale( double factor ) {
scale = factor; scale = factor;
anchor.x *= factor;
anchor.y *= factor;
} }
public void scaleBy( double factor ) { public void scaleBy( double factor ) {
@@ -214,6 +208,8 @@ public abstract class Shape extends FilledShape {
}*/ }*/
public AffineTransform getTransform() { public AffineTransform getTransform() {
Point2D.Double anchor = getAnchorPoint();
AffineTransform transform = new AffineTransform(); AffineTransform transform = new AffineTransform();
transform.translate(x, y); transform.translate(x, y);
transform.rotate(Math.toRadians(rotation)); transform.rotate(Math.toRadians(rotation));
@@ -237,17 +233,17 @@ public abstract class Shape extends FilledShape {
* matrix an. Wird u.A. von der {@link ShapeGroup} verwendet. * matrix an. Wird u.A. von der {@link ShapeGroup} verwendet.
* *
* @param graphics * @param graphics
* @param pVerzerrung * @param transform
*/ */
public void draw( Graphics2D graphics, AffineTransform pVerzerrung ) { public void draw( Graphics2D graphics, AffineTransform transform ) {
if( !visible ) { if( !visible ) {
return; return;
} }
java.awt.Shape shape = getShape(); java.awt.Shape shape = getShape();
if( shape != null ) { if( shape != null ) {
if( pVerzerrung != null ) { if( transform != null ) {
shape = pVerzerrung.createTransformedShape(shape); shape = transform.createTransformedShape(shape);
} }
Color currentColor = graphics.getColor(); Color currentColor = graphics.getColor();

View File

@@ -13,6 +13,10 @@ public class ShapeGroup extends Shape {
private List<Shape> shapes; private List<Shape> shapes;
protected double width = -1.0;
protected double height = -1.0;
public ShapeGroup() { public ShapeGroup() {
super(); super();
shapes = new ArrayList<>(10); shapes = new ArrayList<>(10);
@@ -29,7 +33,7 @@ public class ShapeGroup extends Shape {
for( Shape pShape : shapes ) { for( Shape pShape : shapes ) {
this.shapes.add(pShape); this.shapes.add(pShape);
} }
setAnchor(CENTER); this.anchor = Options.Direction.CENTER;
} }
public Shape copy() { public Shape copy() {
@@ -41,6 +45,7 @@ public class ShapeGroup extends Shape {
for( Shape shape : shapes ) { for( Shape shape : shapes ) {
add(shape, false); add(shape, false);
} }
invalidateBounds();
} }
public void add( Shape pShape, boolean relative ) { public void add( Shape pShape, boolean relative ) {
@@ -49,15 +54,18 @@ public class ShapeGroup extends Shape {
pShape.y = pShape.y - y; pShape.y = pShape.y - y;
} }
shapes.add(pShape); shapes.add(pShape);
invalidateBounds();
} }
public void removeAll() { public void removeAll() {
shapes.clear(); shapes.clear();
invalidateBounds();
} }
public List<Shape> getShapes() { public List<Shape> getShapes() {
return shapes; return shapes;
} }
public <ShapeType extends Shape> List<ShapeType> getShapes( Class<ShapeType> typeClass ) { public <ShapeType extends Shape> List<ShapeType> getShapes( Class<ShapeType> typeClass ) {
LinkedList<ShapeType> list = new LinkedList<>(); LinkedList<ShapeType> list = new LinkedList<>();
for( Shape s: shapes ) { for( Shape s: shapes ) {
@@ -70,6 +78,7 @@ public class ShapeGroup extends Shape {
public void remove( Shape shape ) { public void remove( Shape shape ) {
shapes.remove(shape); shapes.remove(shape);
invalidateBounds();
} }
public Shape get( int index ) { public Shape get( int index ) {
@@ -89,22 +98,39 @@ public class ShapeGroup extends Shape {
} }
@Override @Override
public void setAnchor( Options.Direction anchor ) { public double getWidth() {
if( width < 0 ) {
calculateBounds();
}
return width;
}
@Override
public double getHeight() {
if( height < 0 ) {
calculateBounds();
}
return height;
}
private void invalidateBounds() {
width = -1.0;
height = -1.0;
}
private void calculateBounds() {
double minx = Double.MAX_VALUE, miny = Double.MAX_VALUE, double minx = Double.MAX_VALUE, miny = Double.MAX_VALUE,
maxx = Double.MIN_VALUE, maxy = Double.MIN_VALUE; maxx = Double.MIN_VALUE, maxy = Double.MIN_VALUE;
for( Shape pShape : shapes ) { for( Shape pShape : shapes ) {
Rectangle bounds = pShape.getBounds(); Bounds bounds = pShape.getBounds();
if( bounds.x < minx ) minx = Math.min(minx, bounds.x);
minx = bounds.x; maxx = Math.max(maxx, bounds.x+bounds.width);
if( bounds.y < miny ) miny = Math.min(miny, bounds.y);
miny = bounds.y; maxy = Math.max(maxy, bounds.y+bounds.height);
if( bounds.x+bounds.width > maxx )
maxx = bounds.x+bounds.width;
if( bounds.y+bounds.height > maxy )
maxy = bounds.y+bounds.height;
} }
calculateAnchor(maxx-minx, maxy-miny, anchor); width = maxx-minx;
height = maxy-miny;
} }
@Override @Override
@@ -117,20 +143,22 @@ public class ShapeGroup extends Shape {
} }
@Override @Override
public void draw( Graphics2D graphics, AffineTransform pVerzerrung ) { public void draw( Graphics2D graphics, AffineTransform transform ) {
if( !visible ) { if( !visible ) {
return; return;
} }
/*
AffineTransform verzerrung = new AffineTransform(); AffineTransform verzerrung = new AffineTransform();
verzerrung.translate(x, y); verzerrung.translate(x, y);
verzerrung.rotate(Math.toRadians(rotation)); verzerrung.rotate(Math.toRadians(rotation));
//verzerrung.scale(skalierung, skalierung); //verzerrung.scale(skalierung, skalierung);
verzerrung.translate(-anchor.x, -anchor.y); verzerrung.translate(-anchor.x, -anchor.y);
*/
for( Shape f: shapes ) { for( Shape f: shapes ) {
AffineTransform af = f.getTransform(); AffineTransform af = f.getTransform();
af.preConcatenate(verzerrung); af.preConcatenate(transform);
f.draw(graphics, af); f.draw(graphics, af);
} }
} }

View File

@@ -25,6 +25,42 @@ public class Text extends Shape {
copyFrom(text); copyFrom(text);
} }
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public Font getFont() {
return font;
}
public void setFontsize( double size ) {
font = font.deriveFont((float) size);
calculateBounds();
}
public String getText() {
return text;
}
public void setText( String pText ) {
text = pText;
calculateBounds();
}
private void calculateBounds() {
//GraphicsDevice gd;
//gd.getDefaultConfiguration().createCompatibleImage(1,1);
Canvas metricsCanvas = new Canvas();
FontMetrics metrics = metricsCanvas.getFontMetrics(font);
width = metrics.stringWidth(text);
//height = metrics.getHeight();
height = metrics.getDescent() + metrics.getAscent();
}
public Shape copy() { public Shape copy() {
return new Text(this); return new Text(this);
} }
@@ -36,6 +72,7 @@ public class Text extends Shape {
Text pText = (Text) shape; Text pText = (Text) shape;
this.text = pText.getText(); this.text = pText.getText();
this.font = pText.getFont(); this.font = pText.getFont();
calculateBounds();
} }
} }
@@ -45,50 +82,13 @@ public class Text extends Shape {
setFontsize(font.getSize2D() * factor); setFontsize(font.getSize2D() * factor);
} }
public Font getFont() {
return font;
}
public void setFontsize( double size ) {
font = font.deriveFont((float) size);
setText(text);
}
public String getText() {
return text;
}
public void setText( String pText ) {
text = pText;
Canvas metricsCanvas = new Canvas();
FontMetrics metrics = metricsCanvas.getFontMetrics(font);
width = metrics.stringWidth(text);
height = metrics.getDescent() + metrics.getAscent();
ascent = metrics.getAscent();
setAnchor(CENTER);
}
public double getWidth() {
return width;
}
public double getHeight() {
return height;
}
public void setAnchor( Options.Direction anchor ) {
calculateAnchor(width, ascent - height, anchor);
}
@Override @Override
public java.awt.Shape getShape() { public java.awt.Shape getShape() {
return new Rectangle2D.Double(0, 0, width, height); return new Rectangle2D.Double(0, 0, width, height);
} }
@Override @Override
public void draw( Graphics2D graphics, AffineTransform pVerzerrung ) { public void draw( Graphics2D graphics, AffineTransform transform ) {
if( !visible ) { if( !visible ) {
return; return;
} }
@@ -101,10 +101,10 @@ public class Text extends Shape {
// Neue Werte setzen // Neue Werte setzen
graphics.setFont(font); graphics.setFont(font);
graphics.setColor(strokeColor.getColor()); graphics.setColor(strokeColor.getColor());
graphics.transform(pVerzerrung); graphics.transform(transform);
// Draw text // Draw text
FontMetrics fm = graphics.getFontMetrics(); //FontMetrics fm = graphics.getFontMetrics();
//graphics.drawString(text, (float) (x - fm.stringWidth(text)/2.0), (float) (y + fm.getDescent())); //graphics.drawString(text, (float) (x - fm.stringWidth(text)/2.0), (float) (y + fm.getDescent()));
graphics.drawString(text, 0, 0); graphics.drawString(text, 0, 0);