Refactorings und Javadoc

This commit is contained in:
ngb
2022-07-27 20:36:34 +02:00
parent ebf0135486
commit dcdca893b7
7 changed files with 490 additions and 138 deletions

View File

@@ -11,9 +11,13 @@ import java.awt.RadialGradientPaint;
/** /**
* Eine Ebene, die nur aus einer Farbe (oder einem Farbverlauf) besteht. * Eine Ebene, die nur aus einer Farbe (oder einem Farbverlauf) besteht.
* <p> * <p>
* Ein {@code ColorLayer} ist eine der drei Standardebenen der
* {@link schule.ngb.zm.Zeichenmaschine}.
* <p>
* Die Farbe der Ebene kann beliebig gesetzt werden und kann gut als * Die Farbe der Ebene kann beliebig gesetzt werden und kann gut als
* Hintergundfarbe für eine Szene dienen, oder als halbtransparente "Abdeckung", * Hintergrundfarbe für eine Szene dienen, oder als halbtransparente
* wenn ein {@code ColorLayer} über den anderen Ebenen eingefügt wird. * "Abdeckung", wenn ein {@code ColorLayer} über den anderen Ebenen eingefügt
* wird.
*/ */
@SuppressWarnings( "unused" ) @SuppressWarnings( "unused" )
public class ColorLayer extends Layer { public class ColorLayer extends Layer {

View File

@@ -8,55 +8,102 @@ import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
/**
* Ein Layer um {@link Drawable} Objekte zu zeichnen.
* <p>
* Objekte, die das {@code Drawable} Interface implementieren, können der Ebene
* hinzugefügt werden. Die Ebene sorgt dafür, dass alle {@code Drawable}s einmal
* pro Frame über ihre {@link Drawable#draw(Graphics2D)} Methode gezeichnet.
*/
@SuppressWarnings( "unused" )
public class DrawableLayer extends Layer { public class DrawableLayer extends Layer {
protected List<Drawable> drawables = new LinkedList<>(); /**
* Liste der {@link Drawable}s.
*/
protected final List<Drawable> drawables;
/**
* Ob die Ebene bei jedem Aufruf von {@link #draw(Graphics2D)} geleert
* werden soll.
*/
protected boolean clearBeforeDraw = true; protected boolean clearBeforeDraw = true;
/**
* Erstellt eine Ebene in der Standardgröße.
*/
public DrawableLayer() { public DrawableLayer() {
drawables = new LinkedList<>();
} }
/**
* Erstellt eine Ebene mit der angegebenen Größe.
*
* @param width Die Breite der Ebene.
* @param height Die Höhe der Ebene.
*/
public DrawableLayer( int width, int height ) { public DrawableLayer( int width, int height ) {
super(width, height); super(width, height);
drawables = new LinkedList<>();
} }
/**
* Fügt alle angegebenen {@code Drawable}s der Ebene hinzu.
*
* @param drawables Die {@code Drawable} Objekte.
*/
public void add( Drawable... drawables ) { public void add( Drawable... drawables ) {
synchronized( drawables ) { synchronized( this.drawables ) {
for( Drawable d : drawables ) { Collections.addAll(this.drawables, drawables);
this.drawables.add(d);
}
} }
} }
/**
* Gibt eine Liste aller {@code Drawable} Objekte dieser Ebene zurück.
*
* @return Die Liste der {@code Drawable} Objekte.
*/
public java.util.List<Drawable> getDrawables() { public java.util.List<Drawable> getDrawables() {
return drawables; return drawables;
} }
/**
* Ob die Ebene bei jedem Frame automatisch gelöscht wird.
*
* @return {@code true}, wenn die Ebene vorm Zeichnen gelöscht wird,
* {@code false} sonst.
*/
public boolean isClearBeforeDraw() { public boolean isClearBeforeDraw() {
return clearBeforeDraw; return clearBeforeDraw;
} }
/**
* Stellt ein, ob die Ebene vorm Zeichnen gelöscht werden soll.
*
* @param pClearBeforeDraw Ob die Ebene vorm Zeichnen gelöscht werden
* soll.
*/
public void setClearBeforeDraw( boolean pClearBeforeDraw ) { public void setClearBeforeDraw( boolean pClearBeforeDraw ) {
this.clearBeforeDraw = pClearBeforeDraw; this.clearBeforeDraw = pClearBeforeDraw;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public void draw( Graphics2D pGraphics ) { public void draw( Graphics2D graphics ) {
if( clearBeforeDraw ) { if( clearBeforeDraw ) {
clear(); clear();
} }
synchronized( drawables ) { List<Drawable> it = List.copyOf(drawables);
List<Drawable> it = List.copyOf(drawables); for( Drawable d : it ) {
for( Drawable d : it ) { if( d.isVisible() ) {
if( d.isVisible() ) { d.draw(drawing);
d.draw(drawing);
}
} }
} }
super.draw(pGraphics); super.draw(graphics);
} }
} }

View File

@@ -1,5 +1,6 @@
package schule.ngb.zm.layers; package schule.ngb.zm.layers;
import schule.ngb.zm.Color;
import schule.ngb.zm.Layer; import schule.ngb.zm.Layer;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import schule.ngb.zm.util.io.ImageLoader; import schule.ngb.zm.util.io.ImageLoader;
@@ -8,106 +9,413 @@ import java.awt.*;
import java.awt.geom.*; import java.awt.geom.*;
import java.util.Stack; import java.util.Stack;
/**
* Eine Ebene auf der direkt gezeichnet werden kann.
* <p>
* Ein {@code DrawingLayer} ist eine der drei Standardebenen der
* {@link schule.ngb.zm.Zeichenmaschine}.
*/
public class DrawingLayer extends Layer { public class DrawingLayer extends Layer {
protected schule.ngb.zm.Color fillColor = DEFAULT_FILLCOLOR; /**
* Aktuelle Füllfarbe.
*/
protected Color fillColor = DEFAULT_FILLCOLOR;
protected schule.ngb.zm.Color strokeColor = DEFAULT_STROKECOLOR; /**
* Der aktuelle Farbverlauf oder {@code null}, wenn aktuell kein
* Farbverlauf gesetzt ist.
*/
protected Paint fill = null;
/**
* Aktuelle Konturfarbe.
*/
protected Color strokeColor = DEFAULT_STROKECOLOR;
/**
* Aktuelle Dicke der Konturlinie.
*/
protected double strokeWeight = DEFAULT_STROKEWEIGHT; protected double strokeWeight = DEFAULT_STROKEWEIGHT;
/**
* Art der Konturlinie.
*/
protected Options.StrokeType strokeType = SOLID; protected Options.StrokeType strokeType = SOLID;
/**
* Standardanker für Formen.
*/
private Options.Direction default_anchor = CENTER; private Options.Direction default_anchor = CENTER;
/**
* Wiederverwendbarer Speicher für eine Linie.
*/
protected Line2D.Double line = new Line2D.Double(); protected Line2D.Double line = new Line2D.Double();
/**
* Wiederverwendbarer Speicher für eine Ellipse.
*/
protected Ellipse2D.Double ellipse = new Ellipse2D.Double(); protected Ellipse2D.Double ellipse = new Ellipse2D.Double();
/**
* Wiederverwendbarer Speicher für ein Rechteck.
*/
protected Rectangle2D.Double rect = new Rectangle2D.Double(); protected Rectangle2D.Double rect = new Rectangle2D.Double();
/**
* Wiederverwendbarer Speicher für einen Kreisbogen.
*/
protected Arc2D.Double arc = new Arc2D.Double(); protected Arc2D.Double arc = new Arc2D.Double();
/**
* Wiederverwendbarer Speicher für einen Pfad.
*/
protected Path2D.Double path = new Path2D.Double(); protected Path2D.Double path = new Path2D.Double();
/**
* Ob ein individueller Pfad gestartet wurde.
*/
private boolean pathStarted = false; private boolean pathStarted = false;
private Stack<AffineTransform> transformStack = new Stack<>(); /**
* Stapel für zwischengespeicherte Transformationsmatrizen.
private FontMetrics fontMetrics = null; */
private final Stack<AffineTransform> transformStack;
// private FontMetrics fontMetrics;
/**
* Erstellt eine Ebene in der Standardgröße.
*/
public DrawingLayer() { public DrawingLayer() {
super(); super();
transformStack = new Stack<>();
transformStack.push(new AffineTransform()); transformStack.push(new AffineTransform());
fontMetrics = drawing.getFontMetrics(); // fontMetrics = drawing.getFontMetrics();
} }
/**
* Erstellt eine Ebene mit der angegebenen Größe.
*
* @param width Die Breite der Ebene.
* @param height Die Höhe der Ebene.
*/
public DrawingLayer( int width, int height ) { public DrawingLayer( int width, int height ) {
super(width, height); super(width, height);
transformStack = new Stack<>();
transformStack.push(new AffineTransform()); transformStack.push(new AffineTransform());
fontMetrics = drawing.getFontMetrics(); // fontMetrics = drawing.getFontMetrics();
} }
public schule.ngb.zm.Color getColor() { /**
* Gibt die aktuelle Füllfarbe zurück.
*
* @return Die aktuelle Füllfarbe.
*/
public Color getFillColor() {
return fillColor; return fillColor;
} }
public void setFillColor( int gray ) { /**
setFillColor(gray, gray, gray, 255); * Setzt die Füllfarbe auf die angegebene Farbe.
} *
* @param color Die neue Füllfarbe oder {@code null}.
public void setFillColor( schule.ngb.zm.Color color ) { * @see Color
*/
public void setFillColor( Color color ) {
fillColor = color; fillColor = color;
drawing.setColor(color.getJavaColor()); drawing.setColor(color.getJavaColor());
} }
public void noFill() { /**
fillColor = null; * Setzt die Füllfarbe auf die angegebene Farbe und setzt die Transparenz
* auf den angegebenen Wert. 0 is komplett durchsichtig und 255 komplett
* deckend.
*
* @param color Die neue Füllfarbe oder {@code null}.
* @param alpha Ein Transparenzwert zwischen 0 und 255.
* @see Color#Color(Color, int)
*/
public void setFillColor( Color color, int alpha ) {
setFillColor(new Color(color, alpha));
} }
/**
* Setzt die Füllfarbe auf einen Grauwert mit der angegebenen Intensität. 0
* entspricht schwarz, 255 entspricht weiß.
*
* @param gray Ein Grauwert zwischen 0 und 255.
* @see Color#Color(int)
*/
public void setFillColor( int gray ) {
setFillColor(gray, gray, gray, 255);
}
/**
* Setzt die Füllfarbe auf einen Grauwert mit der angegebenen Intensität und
* dem angegebenen Transparenzwert. Der Grauwert 0 entspricht schwarz, 255
* entspricht weiß.
*
* @param gray Ein Grauwert zwischen 0 und 255.
* @param alpha Ein Transparenzwert zwischen 0 und 255.
* @see Color#Color(int, int)
*/
public void setFillColor( int gray, int alpha ) { public void setFillColor( int gray, int alpha ) {
setFillColor(gray, gray, gray, alpha); setFillColor(gray, gray, gray, alpha);
} }
/**
* Setzt die Füllfarbe auf die Farbe mit den angegebenen Rot-, Grün- und
* Blauanteilen.
*
* @param red Der Rotanteil der Farbe zwischen 0 und 255.
* @param green Der Grünanteil der Farbe zwischen 0 und 255.
* @param blue Der Blauanteil der Farbe zwischen 0 und 255.
* @see Color#Color(int, int, int)
* @see <a
* href="https://de.wikipedia.org/wiki/RGB-Farbraum">https://de.wikipedia.org/wiki/RGB-Farbraum</a>
*/
public void setFillColor( int red, int green, int blue ) { public void setFillColor( int red, int green, int blue ) {
setFillColor(red, green, blue, 255); setFillColor(red, green, blue, 255);
} }
/**
* Setzt die Füllfarbe auf die Farbe mit den angegebenen Rot-, Grün- und
* Blauanteilen und dem angegebenen Transparenzwert.
*
* @param red Der Rotanteil der Farbe zwischen 0 und 255.
* @param green Der Grünanteil der Farbe zwischen 0 und 255.
* @param blue Der Blauanteil der Farbe zwischen 0 und 255.
* @param alpha Ein Transparenzwert zwischen 0 und 25
* @see Color#Color(int, int, int, int)
* @see <a
* href="https://de.wikipedia.org/wiki/RGB-Farbraum">https://de.wikipedia.org/wiki/RGB-Farbraum</a>
*/
public void setFillColor( int red, int green, int blue, int alpha ) { public void setFillColor( int red, int green, int blue, int alpha ) {
setFillColor(new schule.ngb.zm.Color(red, green, blue, alpha)); setFillColor(new schule.ngb.zm.Color(red, green, blue, alpha));
} }
public schule.ngb.zm.Color getStrokeColor() { /**
* Entfernt die Füllung der Form.
*/
public void noFill() {
fillColor = null;
}
/**
* Setzt die Füllfarbe auf den Standardwert zurück.
*
* @see schule.ngb.zm.Constants#DEFAULT_FILLCOLOR
*/
public void resetFill() {
setFillColor(DEFAULT_FILLCOLOR);
noGradient();
}
/**
* Setzt die Füllung auf einen linearen Farbverlauf, der am Punkt
* ({@code fromX}, {@code fromY}) mit der Farbe {@code from} startet und am
* Punkt (({@code toX}, {@code toY}) mit der Farbe {@code to} endet.
*
* @param fromX x-Koordinate des Startpunktes.
* @param fromY y-Koordinate des Startpunktes.
* @param from Farbe am Startpunkt.
* @param toX x-Koordinate des Endpunktes.
* @param toY y-Koordinate des Endpunktes.
* @param to Farbe am Endpunkt.
*/
public void setGradient( double fromX, double fromY, Color from, double toX, double toY, Color to ) {
setFillColor(from);
fill = new GradientPaint(
(float) fromX, (float) fromY, from.getJavaColor(),
(float) toX, (float) toY, to.getJavaColor()
);
}
/**
* Setzt die Füllung auf einen kreisförmigen (radialen) Farbverlauf, mit dem
* Zentrum im Punkt ({@code centerX}, {@code centerY}) und dem angegebenen
* Radius. Der Verlauf starte im Zentrum mit der Farbe {@code from} und
* endet am Rand des durch den Radius beschriebenen Kreises mit der Farbe
* {@code to}.
*
* @param centerX x-Koordinate des Kreismittelpunktes.
* @param centerY y-Koordinate des Kreismittelpunktes.
* @param radius Radius des Kreises.
* @param from Farbe im Zentrum des Kreises.
* @param to Farbe am Rand des Kreises.
*/
public void setGradient( double centerX, double centerY, double radius, Color from, Color to ) {
setFillColor(from);
fill = new RadialGradientPaint(
(float) centerX, (float) centerY, (float) radius,
new float[]{0f, 1f},
new java.awt.Color[]{from.getJavaColor(), to.getJavaColor()});
}
/**
* Entfernt den Farbverlauf von der Form.
*/
public void noGradient() {
fill = null;
}
/**
* Gibt die aktuelle Farbe der Konturlinie zurück.
*
* @return Die Konturfarbe oder {@code null}.
*/
public Color getStrokeColor() {
return strokeColor; return strokeColor;
} }
public void setStrokeColor( int gray ) { /**
setStrokeColor(gray, gray, gray, 255); * Setzt die Farbe der Konturlinie auf die angegebene Farbe.
} *
* @param color Die neue Farbe der Konturlinie.
public void setStrokeColor( schule.ngb.zm.Color color ) { * @see Color
*/
public void setStrokeColor( Color color ) {
strokeColor = color; strokeColor = color;
drawing.setColor(color.getJavaColor()); drawing.setColor(color.getJavaColor());
} }
public void noStroke() { /**
strokeColor = null; * Setzt die Farbe der Konturlinie auf die angegebene Farbe und setzt die
* Transparenz auf den angegebenen Wert. 0 is komplett durchsichtig und 255
* komplett deckend.
*
* @param color Die neue Farbe der Konturlinie oder {@code null}.
* @param alpha Ein Transparenzwert zwischen 0 und 255.
* @see Color#Color(Color, int)
*/
public void setStrokeColor( Color color, int alpha ) {
setStrokeColor(new Color(color, alpha));
} }
/**
* Setzt die Farbe der Konturlinie auf einen Grauwert mit der angegebenen
* Intensität. 0 entspricht schwarz, 255 entspricht weiß.
*
* @param gray Ein Grauwert zwischen 0 und 255.
* @see Color#Color(int)
*/
public void setStrokeColor( int gray ) {
setStrokeColor(gray, gray, gray, 255);
}
/**
* Setzt die Farbe der Konturlinie auf einen Grauwert mit der angegebenen
* Intensität und dem angegebenen Transparenzwert. Der Grauwert 0 entspricht
* schwarz, 255 entspricht weiß.
*
* @param gray Ein Grauwert zwischen 0 und 255.
* @param alpha Ein Transparenzwert zwischen 0 und 255.
* @see Color#Color(int, int)
*/
public void setStrokeColor( int gray, int alpha ) { public void setStrokeColor( int gray, int alpha ) {
setStrokeColor(gray, gray, gray, alpha); setStrokeColor(gray, gray, gray, alpha);
} }
/**
* Setzt die Farbe der Konturlinie auf die Farbe mit den angegebenen Rot-,
* Grün- und Blauanteilen.
*
* @param red Der Rotanteil der Farbe zwischen 0 und 255.
* @param green Der Grünanteil der Farbe zwischen 0 und 255.
* @param blue Der Blauanteil der Farbe zwischen 0 und 255.
* @see Color#Color(int, int, int)
* @see <a
* href="https://de.wikipedia.org/wiki/RGB-Farbraum">https://de.wikipedia.org/wiki/RGB-Farbraum</a>
*/
public void setStrokeColor( int red, int green, int blue ) { public void setStrokeColor( int red, int green, int blue ) {
setStrokeColor(red, green, blue, 255); setStrokeColor(red, green, blue, 255);
} }
/**
* Setzt die Farbe der Konturlinie auf die Farbe mit den angegebenen Rot-,
* Grün- und Blauanteilen und dem angegebenen Transparenzwert.
*
* @param red Der Rotanteil der Farbe zwischen 0 und 255.
* @param green Der Grünanteil der Farbe zwischen 0 und 255.
* @param blue Der Blauanteil der Farbe zwischen 0 und 255.
* @param alpha Ein Transparenzwert zwischen 0 und 25
* @see Color#Color(int, int, int, int)
* @see <a
* href="https://de.wikipedia.org/wiki/RGB-Farbraum">https://de.wikipedia.org/wiki/RGB-Farbraum</a>
*/
public void setStrokeColor( int red, int green, int blue, int alpha ) { public void setStrokeColor( int red, int green, int blue, int alpha ) {
setStrokeColor(new schule.ngb.zm.Color(red, green, blue, alpha)); setStrokeColor(new schule.ngb.zm.Color(red, green, blue, alpha));
} }
public void setStrokeWeight( double pWeight ) { /**
strokeWeight = pWeight; * Entfernt die Kontur der Form.
*/
public void noStroke() {
strokeColor = null;
}
/**
* Setzt die Farbe der Konturlinie auf die Standardwerte zurück.
*
* @see schule.ngb.zm.Constants#DEFAULT_STROKECOLOR
* @see schule.ngb.zm.Constants#DEFAULT_STROKEWEIGHT
* @see schule.ngb.zm.Constants#SOLID
*/
public void resetStroke() {
setStrokeColor(DEFAULT_STROKECOLOR);
setStrokeWeight(DEFAULT_STROKEWEIGHT);
setStrokeType(SOLID);
}
/**
* Gibt die Dicke der Konturlinie zurück.
*
* @return Die aktuelle Dicke der Linie.
*/
public double getStrokeWeight() {
return strokeWeight;
}
/**
* Setzt die Dicke der Konturlinie. Die Dicke muss größer 0 sein. Wird 0
* übergeben, dann wird keine Kontur mehr angezeigt.
*
* @param weight Die Dicke der Konturlinie.
*/
public void setStrokeWeight( double weight ) {
strokeWeight = weight;
drawing.setStroke(createStroke()); drawing.setStroke(createStroke());
} }
/**
* Gibt die Art der Konturlinie zurück.
*
* @return Die aktuelle Art der Konturlinie.
* @see Options.StrokeType
*/
public Options.StrokeType getStrokeType() {
return strokeType;
}
/**
* Setzt den Typ der Kontur. Erlaubte Werte sind {@link #DASHED},
* {@link #DOTTED} und {@link #SOLID}.
*
* @param type Eine der möglichen Konturarten.
* @see Options.StrokeType
*/
public void setStrokeType( Options.StrokeType type ) {
this.strokeType = type;
}
/**
* Hilfsmethode, um ein {@link Stroke} Objekt mit den aktuellen
* Kontureigenschaften zu erstellen. Der aktuelle {@code Stroke} wird
* zwischengespeichert.
*
* @return Ein {@code Stroke} mit den passenden Kontureigenschaften.
*/
protected Stroke createStroke() { protected Stroke createStroke() {
switch( strokeType ) { switch( strokeType ) {
case DOTTED: case DOTTED:
@@ -130,30 +438,6 @@ public class DrawingLayer extends Layer {
} }
} }
public Options.StrokeType getStrokeType() {
return strokeType;
}
public void setStrokeType( Options.StrokeType type ) {
switch( type ) {
case DASHED:
this.strokeType = DASHED;
break;
case DOTTED:
this.strokeType = DOTTED;
break;
default:
this.strokeType = SOLID;
break;
}
}
public void resetStroke() {
setStrokeColor(DEFAULT_STROKECOLOR);
setStrokeWeight(DEFAULT_STROKEWEIGHT);
setStrokeType(SOLID);
}
public void setAnchor( Options.Direction anchor ) { public void setAnchor( Options.Direction anchor ) {
default_anchor = anchor; default_anchor = anchor;
} }
@@ -194,7 +478,7 @@ public class DrawingLayer extends Layer {
public void pixel( double x, double y ) { public void pixel( double x, double y ) {
// square(x, y, 1); // square(x, y, 1);
buffer.setRGB((int)x, (int)y, fillColor.getRGBA()); buffer.setRGB((int) x, (int) y, fillColor.getRGBA());
} }
public void square( double x, double y, double w ) { public void square( double x, double y, double w ) {
@@ -222,11 +506,11 @@ public class DrawingLayer extends Layer {
} }
public void circle( double x, double y, double r ) { public void circle( double x, double y, double r ) {
ellipse(x, y, r+r, r+r, default_anchor); ellipse(x, y, r + r, r + r, default_anchor);
} }
public void circle( double x, double y, double r, Options.Direction anchor ) { public void circle( double x, double y, double r, Options.Direction anchor ) {
ellipse(x, y, r+r, r+r, anchor); ellipse(x, y, r + r, r + r, anchor);
} }
public void ellipse( double x, double y, double w, double h ) { public void ellipse( double x, double y, double w, double h ) {
@@ -242,7 +526,7 @@ public class DrawingLayer extends Layer {
} }
public void arc( double x, double y, double r, double angle1, double angle2 ) { public void arc( double x, double y, double r, double angle1, double angle2 ) {
arc(x, y, r+r, r+r, angle1, angle2); arc(x, y, r + r, r + r, angle1, angle2);
} }
public void arc( double x, double y, double w, double h, double angle1, double angle2 ) { public void arc( double x, double y, double w, double h, double angle1, double angle2 ) {
@@ -260,7 +544,7 @@ public class DrawingLayer extends Layer {
anchorPoint.x, anchorPoint.y, anchorPoint.x, anchorPoint.y,
w, h, w, h,
//Math.toRadians(angle1), Math.toRadians(angle2 - angle1), //Math.toRadians(angle1), Math.toRadians(angle2 - angle1),
angle1, angle2-angle1, angle1, angle2 - angle1,
Arc2D.OPEN Arc2D.OPEN
); );
@@ -270,7 +554,7 @@ public class DrawingLayer extends Layer {
public void pie( double x, double y, double r, double angle1, double angle2 ) { public void pie( double x, double y, double r, double angle1, double angle2 ) {
while( angle2 < angle1 ) angle2 += 360.0; while( angle2 < angle1 ) angle2 += 360.0;
double d = r+r; double d = r + r;
Point2D.Double anchorPoint = getAnchorPoint(x, y, d, d, CENTER); Point2D.Double anchorPoint = getAnchorPoint(x, y, d, d, CENTER);
/*Shape arc = new Arc2D.Double( /*Shape arc = new Arc2D.Double(
@@ -435,7 +719,7 @@ public class DrawingLayer extends Layer {
} }
public void setFontSize( int size ) { public void setFontSize( int size ) {
setFont(drawing.getFont().deriveFont((float)size)); setFont(drawing.getFont().deriveFont((float) size));
} }
public void setFont( String fontName ) { public void setFont( String fontName ) {
@@ -460,7 +744,7 @@ public class DrawingLayer extends Layer {
private Point2D.Double transformToCanvas( double x, double y ) { private Point2D.Double transformToCanvas( double x, double y ) {
return transformToCanvas(new Point2D.Double(x,y)); return transformToCanvas(new Point2D.Double(x, y));
} }
private Point2D.Double transformToCanvas( Point2D.Double pPoint ) { private Point2D.Double transformToCanvas( Point2D.Double pPoint ) {
@@ -470,7 +754,7 @@ public class DrawingLayer extends Layer {
} }
private Point2D.Double transformToUser( double x, double y ) { private Point2D.Double transformToUser( double x, double y ) {
return transformToUser(new Point2D.Double(x,y)); return transformToUser(new Point2D.Double(x, y));
} }
private Point2D.Double transformToUser( Point2D.Double pPoint ) { private Point2D.Double transformToUser( Point2D.Double pPoint ) {

View File

@@ -1,11 +1,12 @@
package schule.ngb.zm.layers; package schule.ngb.zm.layers;
import java.awt.Graphics2D;
import java.awt.Image;
import schule.ngb.zm.Layer; import schule.ngb.zm.Layer;
import schule.ngb.zm.util.io.ImageLoader; import schule.ngb.zm.util.io.ImageLoader;
import java.awt.Graphics2D;
import java.awt.Image;
@SuppressWarnings( "unused" )
public class ImageLayer extends Layer { public class ImageLayer extends Layer {
protected Image image; protected Image image;
@@ -16,20 +17,20 @@ public class ImageLayer extends Layer {
protected boolean redraw = true; protected boolean redraw = true;
public ImageLayer(String source) { public ImageLayer( String source ) {
image = ImageLoader.loadImage(source); image = ImageLoader.loadImage(source);
} }
public ImageLayer(Image image) { public ImageLayer( Image image ) {
this.image = image; this.image = image;
} }
public ImageLayer(int width, int height, Image image) { public ImageLayer( int width, int height, Image image ) {
super(width, height); super(width, height);
this.image = image; this.image = image;
} }
public void setImage(Image image) { public void setImage( Image image ) {
this.image = image; this.image = image;
redraw = true; redraw = true;
} }
@@ -38,7 +39,7 @@ public class ImageLayer extends Layer {
return x; return x;
} }
public void setX(double pX) { public void setX( double pX ) {
this.x = pX; this.x = pX;
redraw = true; redraw = true;
} }
@@ -47,7 +48,7 @@ public class ImageLayer extends Layer {
return y; return y;
} }
public void setY(double pY) { public void setY( double pY ) {
this.y = pY; this.y = pY;
redraw = true; redraw = true;
} }
@@ -59,8 +60,8 @@ public class ImageLayer extends Layer {
} }
@Override @Override
public void draw(Graphics2D graphics) { public void draw( Graphics2D graphics ) {
if (redraw && visible) { if( redraw && visible ) {
drawing.drawImage(image, (int) x, (int) y, null); drawing.drawImage(image, (int) x, (int) y, null);
redraw = false; redraw = false;
} }

View File

@@ -4,42 +4,46 @@ import schule.ngb.zm.Color;
import schule.ngb.zm.Layer; import schule.ngb.zm.Layer;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import java.awt.*; import java.awt.BasicStroke;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Stroke;
import java.util.LinkedList; import java.util.LinkedList;
@SuppressWarnings( "unused" )
public final class Shape2DLayer extends Layer { public final class Shape2DLayer extends Layer {
protected schule.ngb.zm.Color strokeColor = DEFAULT_STROKECOLOR; private schule.ngb.zm.Color strokeColor = DEFAULT_STROKECOLOR;
protected schule.ngb.zm.Color fillColor = DEFAULT_FILLCOLOR; private schule.ngb.zm.Color fillColor = DEFAULT_FILLCOLOR;
protected double strokeWeight = DEFAULT_STROKEWEIGHT; private double strokeWeight = DEFAULT_STROKEWEIGHT;
protected Options.StrokeType strokeType = SOLID; private Options.StrokeType strokeType = SOLID;
private LinkedList<java.awt.Shape> shapes; private final LinkedList<java.awt.Shape> shapes;
private boolean instantDraw = false; private boolean instantDraw = false;
public Shape2DLayer() { public Shape2DLayer() {
super(); super();
shapes = new LinkedList<java.awt.Shape>(); shapes = new LinkedList<>();
} }
public Shape2DLayer( boolean instantDraw ) { public Shape2DLayer( boolean instantDraw ) {
super(); super();
shapes = new LinkedList<java.awt.Shape>(); shapes = new LinkedList<>();
this.instantDraw = instantDraw; this.instantDraw = instantDraw;
} }
public Shape2DLayer( int width, int height ) { public Shape2DLayer( int width, int height ) {
super(width, height); super(width, height);
shapes = new LinkedList<java.awt.Shape>(); shapes = new LinkedList<>();
} }
public Shape2DLayer( int width, int height, boolean instantDraw ) { public Shape2DLayer( int width, int height, boolean instantDraw ) {
super(width, height); super(width, height);
shapes = new LinkedList<java.awt.Shape>(); shapes = new LinkedList<>();
this.instantDraw = instantDraw; this.instantDraw = instantDraw;
} }
@@ -106,7 +110,7 @@ public final class Shape2DLayer extends Layer {
drawing.setStroke(createStroke()); drawing.setStroke(createStroke());
} }
protected Stroke createStroke() { private Stroke createStroke() {
switch( strokeType ) { switch( strokeType ) {
case DOTTED: case DOTTED:
return new BasicStroke( return new BasicStroke(
@@ -153,7 +157,7 @@ public final class Shape2DLayer extends Layer {
} }
@Override @Override
public void draw( Graphics2D pGraphics ) { public void draw( Graphics2D graphics ) {
if( !instantDraw ) { if( !instantDraw ) {
for( Shape shape : shapes ) { for( Shape shape : shapes ) {
drawing.setColor(fillColor.getJavaColor()); drawing.setColor(fillColor.getJavaColor());
@@ -164,7 +168,7 @@ public final class Shape2DLayer extends Layer {
} }
} }
super.draw(pGraphics); super.draw(graphics);
} }
} }

View File

@@ -10,13 +10,20 @@ import java.awt.Graphics2D;
import java.util.*; import java.util.*;
import java.util.function.DoubleUnaryOperator; import java.util.function.DoubleUnaryOperator;
/**
* Ein Layer um {@link Shape} Objekte zu zeichnen.
* <p>
* Ein {@code ShapesLayer} ist eine der drei Standardebenen der
* {@link schule.ngb.zm.Zeichenmaschine}.
*/
@SuppressWarnings( "unused" )
public class ShapesLayer extends Layer { public class ShapesLayer extends Layer {
protected boolean clearBeforeDraw = true; protected boolean clearBeforeDraw = true;
private List<Shape> shapes; private final List<Shape> shapes;
private List<Animation<? extends Shape>> animations; private final List<Animation<? extends Shape>> animations;
public ShapesLayer() { public ShapesLayer() {
super(); super();
@@ -37,7 +44,7 @@ public class ShapesLayer extends Layer {
public <ST extends Shape> ST getShape( Class<ST> shapeClass ) { public <ST extends Shape> ST getShape( Class<ST> shapeClass ) {
for( Shape s : shapes ) { for( Shape s : shapes ) {
if( shapeClass.isInstance(s) ) { if( shapeClass.isInstance(s) ) {
return (ST) s; return shapeClass.cast(s);
} }
} }
return null; return null;
@@ -51,7 +58,7 @@ public class ShapesLayer extends Layer {
List<ST> result = new LinkedList<>(); List<ST> result = new LinkedList<>();
for( Shape s : shapes ) { for( Shape s : shapes ) {
if( shapeClass.isInstance(s) ) { if( shapeClass.isInstance(s) ) {
result.add((ST) s); result.add(shapeClass.cast(s));
} }
} }
return result; return result;
@@ -59,17 +66,13 @@ public class ShapesLayer extends Layer {
public void add( Shape... shapes ) { public void add( Shape... shapes ) {
synchronized( this.shapes ) { synchronized( this.shapes ) {
for( Shape s : shapes ) { Collections.addAll(this.shapes, shapes);
this.shapes.add(s);
}
} }
} }
public void add( Collection<Shape> shapes ) { public void add( Collection<Shape> shapes ) {
synchronized( this.shapes ) { synchronized( this.shapes ) {
for( Shape s : shapes ) { this.shapes.addAll(shapes);
this.shapes.add(s);
}
} }
} }
@@ -83,9 +86,7 @@ public class ShapesLayer extends Layer {
public void remove( Collection<Shape> shapes ) { public void remove( Collection<Shape> shapes ) {
synchronized( this.shapes ) { synchronized( this.shapes ) {
for( Shape s : shapes ) { this.shapes.removeAll(shapes);
this.shapes.remove(s);
}
} }
} }
@@ -116,9 +117,9 @@ public class ShapesLayer extends Layer {
anim.start(); anim.start();
} }
@SafeVarargs
public void play( Animation<? extends Shape>... anims ) { public final void play( Animation<? extends Shape>... anims ) {
for( Animation<? extends Shape> anim: anims ) { for( Animation<? extends Shape> anim : anims ) {
this.animations.add(anim); this.animations.add(anim);
anim.start(); anim.start();
} }
@@ -141,13 +142,13 @@ public class ShapesLayer extends Layer {
anim.update(delta); anim.update(delta);
if( !anim.isActive() ) { if( !anim.isActive() ) {
animations.remove(anim); it.remove();
} }
} }
} }
@Override @Override
public void draw( Graphics2D pGraphics ) { public void draw( Graphics2D graphics ) {
if( clearBeforeDraw ) { if( clearBeforeDraw ) {
clear(); clear();
} }
@@ -161,7 +162,7 @@ public class ShapesLayer extends Layer {
} }
} }
super.draw(pGraphics); super.draw(graphics);
} }
} }

View File

@@ -6,12 +6,14 @@ import schule.ngb.zm.Options;
import schule.ngb.zm.Vector; import schule.ngb.zm.Vector;
import schule.ngb.zm.shapes.FilledShape; import schule.ngb.zm.shapes.FilledShape;
import java.awt.*; import java.awt.Graphics2D;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Stack; import java.util.Stack;
@SuppressWarnings( "unused" )
public class TurtleLayer extends Layer { public class TurtleLayer extends Layer {
// Rotating by the clock // Rotating by the clock
@@ -39,7 +41,7 @@ public class TurtleLayer extends Layer {
public static final int H12 = 360; public static final int H12 = 360;
private static Stack<Color> turtleColors; private final static Stack<Color> turtleColors;
static { static {
turtleColors = new Stack<>(); turtleColors = new Stack<>();
@@ -51,9 +53,9 @@ public class TurtleLayer extends Layer {
turtleColors.add(Color.BLUE); turtleColors.add(Color.BLUE);
} }
private Turtle mainTurtle = null; private final Turtle mainTurtle;
private ArrayList<Turtle> turtles = new ArrayList<Turtle>(6); private final List<Turtle> turtles = new ArrayList<>(6);
public TurtleLayer() { public TurtleLayer() {
super(); super();
@@ -255,8 +257,8 @@ public class TurtleLayer extends Layer {
mainTurtle.resetStroke(); mainTurtle.resetStroke();
} }
public void addPosToPath() { public void beginPath() {
mainTurtle.addPosToPath(); mainTurtle.beginPath();
} }
public void closePath() { public void closePath() {
@@ -266,9 +268,12 @@ public class TurtleLayer extends Layer {
// End of delegate methods (auto-generated) // End of delegate methods (auto-generated)
/**
* Die Turtle der Zeichenmaschine.
*/
public class Turtle extends FilledShape { public class Turtle extends FilledShape {
private static final int STD_SIZE = 12; private static final int DEFAULT_SIZE = 12;
boolean penDown = true; boolean penDown = true;
@@ -282,7 +287,22 @@ public class TurtleLayer extends Layer {
boolean pathOpen = false; boolean pathOpen = false;
Turtle() {} Turtle() {
}
public void beginPath() {
pathOpen = false;
addPosToPath();
}
public void closePath() {
if( pathOpen ) {
addPosToPath();
path.closePath();
path.trimToSize();
pathOpen = false;
}
}
private void addPosToPath() { private void addPosToPath() {
if( !pathOpen ) { if( !pathOpen ) {
@@ -294,15 +314,6 @@ public class TurtleLayer extends Layer {
} }
} }
private void closePath() {
if( pathOpen ) {
addPosToPath();
path.closePath();
path.trimToSize();
pathOpen = false;
}
}
public void fill() { public void fill() {
closePath(); closePath();
@@ -322,16 +333,16 @@ public class TurtleLayer extends Layer {
-12, -5, 16, 10, 5, 3 -12, -5, 16, 10, 5, 3
);*/ );*/
Path2D path = new Path2D.Double(); Path2D path = new Path2D.Double();
path.moveTo(STD_SIZE, 0); path.moveTo(DEFAULT_SIZE, 0);
path.lineTo(-STD_SIZE, -STD_SIZE/2); path.lineTo(-DEFAULT_SIZE, -DEFAULT_SIZE / 2.0);
path.lineTo(-STD_SIZE, STD_SIZE/2); path.lineTo(-DEFAULT_SIZE, DEFAULT_SIZE / 2.0);
path.lineTo(STD_SIZE, 0); path.lineTo(DEFAULT_SIZE, 0);
AffineTransform verzerrung = new AffineTransform(); AffineTransform verzerrung = new AffineTransform();
verzerrung.translate(position.x, position.y); verzerrung.translate(position.x, position.y);
verzerrung.rotate(Math.toRadians(direction.angle())); verzerrung.rotate(Math.toRadians(direction.angle()));
Shape shape = verzerrung.createTransformedShape(path); java.awt.Shape shape = verzerrung.createTransformedShape(path);
if( strokeColor != null ) { if( strokeColor != null ) {
graphics.setColor(strokeColor.getJavaColor()); graphics.setColor(strokeColor.getJavaColor());