Farbverläufe für Formen und neue Konstantennamen

This commit is contained in:
ngb
2022-07-17 15:45:05 +02:00
parent 3931e610c6
commit 6551bb75c9
15 changed files with 375 additions and 62 deletions

View File

@@ -7,9 +7,10 @@ und diese Projekt folgt [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased] ## [Unreleased]
### Added ### Added
- System für EventListener erstellt - System für EventListener.
- `AudioListener` und `AnimationListener` als erste Anwendungsfälle. - `AudioListener` und `AnimationListener` als erste Anwendungsfälle.
- Pakete für Animationen und Maschinelles-Lernen hinzugefügt - Pakete für Animationen und Maschinelles-Lernen.
- Farbverläufe als Füllung.
### Changed ### Changed
- `update(double)` und `draw()` werden nun in einem eigenen Thread aufgerufen. - `update(double)` und `draw()` werden nun in einem eigenen Thread aufgerufen.

View File

@@ -1,5 +1,10 @@
package schule.ngb.zm; package schule.ngb.zm;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
/** /**
* Repräsentiert eine Farbe in der Zeichenmaschine. * Repräsentiert eine Farbe in der Zeichenmaschine.
* <p> * <p>
@@ -9,7 +14,7 @@ package schule.ngb.zm;
* Eine Farbe hat außerdem einen Transparenzwert zwischen 0 (unsichtbar) und 255 * Eine Farbe hat außerdem einen Transparenzwert zwischen 0 (unsichtbar) und 255
* (deckend). * (deckend).
*/ */
public class Color { public class Color implements Paint {
//@formatter:off //@formatter:off
@@ -146,7 +151,7 @@ public class Color {
* @param alpha Transparentwert zwischen 0 und 255. * @param alpha Transparentwert zwischen 0 und 255.
*/ */
public Color( int red, int green, int blue, int alpha ) { public Color( int red, int green, int blue, int alpha ) {
rgba = ((alpha&0xFF) << 24) | ((red&0xFF) << 16) | ((green&0xFF) << 8) | ((blue&0xFF) << 0); rgba = ((alpha & 0xFF) << 24) | ((red & 0xFF) << 16) | ((green & 0xFF) << 8) | ((blue & 0xFF) << 0);
} }
/** /**
@@ -462,6 +467,23 @@ public class Color {
return new java.awt.Color(rgba, true); return new java.awt.Color(rgba, true);
} }
@Override
public PaintContext createContext( ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds, AffineTransform xform, RenderingHints hints ) {
return getJavaColor().createContext(cm, deviceBounds, userBounds, xform, hints);
}
@Override
public int getTransparency() {
int alpha = getAlpha();
if( alpha == 0xff ) {
return Transparency.OPAQUE;
} else if( alpha == 0 ) {
return Transparency.BITMASK;
} else {
return Transparency.TRANSLUCENT;
}
}
@Override @Override
/** /**
* Prüft, ob ein anderes Objekt zu diesem gleich ist. * Prüft, ob ein anderes Objekt zu diesem gleich ist.
@@ -473,7 +495,9 @@ public class Color {
* @return {@code true}, wenn die Objekte gleich sind, sonst {@code false}. * @return {@code true}, wenn die Objekte gleich sind, sonst {@code false}.
*/ */
public boolean equals( Object obj ) { public boolean equals( Object obj ) {
if( obj == null ) { return false; } if( obj == null ) {
return false;
}
if( obj instanceof Color ) { if( obj instanceof Color ) {
return ((Color) obj).getRGBA() == this.rgba; return ((Color) obj).getRGBA() == this.rgba;
} else if( obj instanceof java.awt.Color ) { } else if( obj instanceof java.awt.Color ) {

View File

@@ -1,17 +1,43 @@
package schule.ngb.zm; package schule.ngb.zm;
import schule.ngb.zm.shapes.Shape;
import java.awt.GradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
/**
* Eine Ebene, die nur aus einer Farbe (oder einem Farbverlauf) besteht.
* <p>
* Die Farbe der Ebene kann beliebig gesetzt werden und kann gut als
* Hintergundfarbe für eine Szene dienen, oder als halbtransparente "Abdeckung",
* wenn ein {@code ColorLayer} über den anderen Ebenen eingefügt wird.
*/
public class ColorLayer extends Layer { public class ColorLayer extends Layer {
private Color background; /**
* Farbe der Ebene.
*/
private Color color;
/**
* Verlauf der Ebene, falls verwendet.
*/
private Paint background;
public ColorLayer( Color color ) { public ColorLayer( Color color ) {
this.background = color; this.color = color;
this.background = color.getJavaColor();
clear(); clear();
} }
public ColorLayer( int width, int height, Color color ) { public ColorLayer( int width, int height, Color color ) {
super(width, height); super(width, height);
this.background = color; this.color = color;
this.background = color.getJavaColor();
clear(); clear();
} }
@@ -22,11 +48,12 @@ public class ColorLayer extends Layer {
} }
public Color getColor() { public Color getColor() {
return background; return color;
} }
public void setColor( Color color ) { public void setColor( Color color ) {
background = color; this.color = color;
this.background = color.getJavaColor();
clear(); clear();
} }
@@ -46,9 +73,45 @@ public class ColorLayer extends Layer {
setColor(new Color(red, green, blue, alpha)); setColor(new Color(red, green, blue, alpha));
} }
public void setGradient( Color from, Color to, Options.Direction dir ) {
double halfW = getWidth()*.5;
double halfH = getHeight()*.5;
Options.Direction inv = dir.inverse();
int fromX = (int)(halfW + inv.x * halfW);
int fromY = (int)(halfH + inv.x * halfH);
int toX = (int)(halfW + dir.x * halfW);
int toY = (int)(halfH + dir.x * halfH);
setGradient(fromX, fromY, from, toX, toY, to);
}
public void setGradient( double fromX, double fromY, Color from, double toX, double toY, Color to ) {
setColor(from);
background = new GradientPaint(
(float)fromX, (float)fromY, from.getJavaColor(),
(float)toX, (float)toY, to.getJavaColor()
);
clear();
}
public void setGradient( Color from, Color to ) {
setGradient(getWidth()*.5, getHeight()*.5, Math.min(getWidth()*.5, getHeight()*.5), from, to);
}
public void setGradient( double centerX, double centerY, double radius, Color from, Color to ) {
setColor(from);
background = new RadialGradientPaint(
(float)centerX, (float)centerY, (float)radius,
new float[]{0f, 1f},
new java.awt.Color[]{from.getJavaColor(), to.getJavaColor()});
clear();
}
@Override @Override
public void clear() { public void clear() {
drawing.setColor(background.getJavaColor()); drawing.setPaint(background);
drawing.fillRect(0, 0, getWidth(), getHeight()); drawing.fillRect(0, 0, getWidth(), getHeight());
} }

View File

@@ -75,42 +75,42 @@ public class Constants {
/** /**
* Standardbreite eines Zeichenfensters. * Standardbreite eines Zeichenfensters.
*/ */
public static final int STD_WIDTH = 400; public static final int DEFAULT_WIDTH = 400;
/** /**
* Standardhöhe eines Zeichenfensters. * Standardhöhe eines Zeichenfensters.
*/ */
public static final int STD_HEIGHT = 400; public static final int DEFAULT_HEIGHT = 400;
/** /**
* Standardwert für die Frames pro Sekunde einer Zeichenmaschine. * Standardwert für die Frames pro Sekunde einer Zeichenmaschine.
*/ */
public static final int STD_FPS = 60; public static final int DEFAULT_FPS = 60;
/** /**
* Standardfarbe der Füllungen. * Standardfarbe der Füllungen.
*/ */
public static final Color STD_FILLCOLOR = Color.WHITE; public static Color DEFAULT_FILLCOLOR = Color.WHITE;
/** /**
* Standardfarbe der Konturen. * Standardfarbe der Konturen.
*/ */
public static final Color STD_STROKECOLOR = Color.BLACK; public static Color DEFAULT_STROKECOLOR = Color.BLACK;
/** /**
* Standardwert für die Dicke der Konturen. * Standardwert für die Dicke der Konturen.
*/ */
public static final double STD_STROKEWEIGHT = 1.0; public static double DEFAULT_STROKEWEIGHT = 1.0;
/** /**
* Standardwert für die Schriftgröße. * Standardwert für die Schriftgröße.
*/ */
public static final int STD_FONTSIZE = 14; public static int DEFAULT_FONTSIZE = 14;
/** /**
* Standardwert für den Abstand von Formen. * Standardwert für den Abstand von Formen.
*/ */
public static final int STD_BUFFER = 10; public static int DEFAULT_BUFFER = 10;
public static int DEFAULT_ANIM_RUNTIME = 1000; public static int DEFAULT_ANIM_RUNTIME = 1000;
@@ -414,7 +414,7 @@ public class Constants {
/** /**
* Aktuell dargestellte Bilder pro Sekunde. * Aktuell dargestellte Bilder pro Sekunde.
*/ */
public static int framesPerSecond = STD_FPS; public static int framesPerSecond = DEFAULT_FPS;
/** /**
* Anzahl der Ticks (Frames), die das Programm bisher läuft. * Anzahl der Ticks (Frames), die das Programm bisher läuft.

View File

@@ -8,11 +8,11 @@ import java.util.Stack;
public class DrawingLayer extends Layer { public class DrawingLayer extends Layer {
protected Color fillColor = STD_FILLCOLOR; protected Color fillColor = DEFAULT_FILLCOLOR;
protected Color strokeColor = STD_STROKECOLOR; protected Color strokeColor = DEFAULT_STROKECOLOR;
protected double strokeWeight = STD_STROKEWEIGHT; protected double strokeWeight = DEFAULT_STROKEWEIGHT;
protected Options.StrokeType strokeType = SOLID; protected Options.StrokeType strokeType = SOLID;
@@ -147,8 +147,8 @@ public class DrawingLayer extends Layer {
} }
public void resetStroke() { public void resetStroke() {
setStrokeColor(STD_STROKECOLOR); setStrokeColor(DEFAULT_STROKECOLOR);
setStrokeWeight(STD_STROKEWEIGHT); setStrokeWeight(DEFAULT_STROKEWEIGHT);
setStrokeType(SOLID); setStrokeType(SOLID);
} }

View File

@@ -0,0 +1,5 @@
package schule.ngb.zm;
public class Gradient {
}

View File

@@ -18,7 +18,7 @@ public abstract class Layer extends Constants implements Drawable, Updatable {
public Layer() { public Layer() {
this(STD_WIDTH, STD_HEIGHT); this(DEFAULT_WIDTH, DEFAULT_HEIGHT);
} }
public Layer( int width, int height ) { public Layer( int width, int height ) {

View File

@@ -5,11 +5,11 @@ import java.util.LinkedList;
public final class Shape2DLayer extends Layer { public final class Shape2DLayer extends Layer {
protected Color strokeColor = STD_STROKECOLOR; protected Color strokeColor = DEFAULT_STROKECOLOR;
protected Color fillColor = STD_FILLCOLOR; protected Color fillColor = DEFAULT_FILLCOLOR;
protected double strokeWeight = STD_STROKEWEIGHT; protected double strokeWeight = DEFAULT_STROKEWEIGHT;
protected Options.StrokeType strokeType = SOLID; protected Options.StrokeType strokeType = SOLID;

View File

@@ -1,6 +1,5 @@
package schule.ngb.zm; package schule.ngb.zm;
import java.awt.Graphics;
import java.util.LinkedList; import java.util.LinkedList;
public class Spielemaschine extends Zeichenmaschine { public class Spielemaschine extends Zeichenmaschine {
@@ -12,7 +11,7 @@ public class Spielemaschine extends Zeichenmaschine {
private GraphicsLayer mainLayer; private GraphicsLayer mainLayer;
public Spielemaschine( String title ) { public Spielemaschine( String title ) {
this(STD_WIDTH, STD_HEIGHT, title); this(DEFAULT_WIDTH, DEFAULT_HEIGHT, title);
} }

View File

@@ -255,7 +255,7 @@ public class Zeichenmaschine extends Constants {
* @param title Der Titel, der oben im Fenster steht. * @param title Der Titel, der oben im Fenster steht.
*/ */
public Zeichenmaschine( String title ) { public Zeichenmaschine( String title ) {
this(STD_WIDTH, STD_HEIGHT, title, true); this(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, true);
} }
/** /**
@@ -270,7 +270,7 @@ public class Zeichenmaschine extends Constants {
* Aufruf von {@code draw()}. * Aufruf von {@code draw()}.
*/ */
public Zeichenmaschine( String title, boolean run_once ) { public Zeichenmaschine( String title, boolean run_once ) {
this(STD_WIDTH, STD_HEIGHT, title, run_once); this(DEFAULT_WIDTH, DEFAULT_HEIGHT, title, run_once);
} }
/** /**
@@ -377,7 +377,7 @@ public class Zeichenmaschine extends Constants {
shapes = getShapesLayer(); shapes = getShapesLayer();
// FPS setzen // FPS setzen
framesPerSecondInternal = STD_FPS; framesPerSecondInternal = DEFAULT_FPS;
this.run_once = run_once; this.run_once = run_once;
// Settings der Unterklasse aufrufen, falls das Fenster vor dem Öffnen // Settings der Unterklasse aufrufen, falls das Fenster vor dem Öffnen

View File

@@ -2,44 +2,201 @@ package schule.ngb.zm.shapes;
import schule.ngb.zm.Color; import schule.ngb.zm.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
/**
* Basisklasse für Formen, die eine Füllung besitzen können.
* <p>
* Formen mit einer Füllung können auch immer eine Konturlinie besitzen.
*/
public abstract class FilledShape extends StrokedShape { public abstract class FilledShape extends StrokedShape {
protected Color fillColor = STD_FILLCOLOR; /**
* Die aktuelle Füllfarbe der Form oder {@code null}, wenn die Form nicht
* gefüllt werden soll.
*/
protected Color fillColor = DEFAULT_FILLCOLOR;
/**
* Der aktuelle Farbverlauf der Form oder {@code null}, wenn die Form keinen
* Farbverlauf besitzt.
*/
protected Paint fill = null;
/**
* Gibt die aktuelle Füllfarbe der Form zurück.
*
* @return Die aktuelle Füllfarbe oder {@code null}.
*/
public Color getFillColor() { public Color getFillColor() {
return fillColor; return fillColor;
} }
/**
* Setzt die Füllfarbe auf die angegebene Farbe.
*
* @param color Die neue Füllfarbe oder {@code null}.
* @see Color#Color(Color)
*/
public void setFillColor( Color color ) { public void setFillColor( Color color ) {
fillColor = color; fillColor = color;
} }
/**
* 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 {@null}.
* @param alpha Ein Transparenzwert zwischen 0 und 255.
* @see Color#Color(Color, int)
*/
public void setFillColor( Color color, int alpha ) { public void setFillColor( Color color, int alpha ) {
setFillColor(new Color(color, 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 ) { public void setFillColor( int gray ) {
setFillColor(gray, gray, gray, 255); setFillColor(gray, gray, gray, 255);
} }
public void noFill() { /**
setFillColor(null); * 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 Color(red, green, blue, alpha)); setFillColor(new Color(red, green, blue, alpha));
} }
/**
* Entfernt die Füllung der Form.
*/
public void noFill() {
setFillColor(null);
noGradient();
}
/**
* Setzt die Füllfarbe auf den Standardwert zurück.
*
* @see schule.ngb.zm.Constants#DEFAULT_FILLCOLOR
*/
public void resetFill() { public void resetFill() {
setFillColor(STD_FILLCOLOR); 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
* @param fromY
* @param from
* @param toX
* @param toY
* @param to
*/
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
* @param centerY
* @param radius
* @param from
* @param to
*/
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;
}
/**
* Hilfsmethode für Unterklassen, um die angegebene Form mit der gesetzten
* Füllung auf den Grafik-Kontext zu zeichnen. Die Methode verändert
* gegebenenfalls die aktuelle Farbe des Grafikobjekts und setzt sie nicht
* auf den Ursprungswert zurück. Dies sollte die aufrufende Unterklasse
* übernehmen.
*
* @param shape Die zu zeichnende Java-AWT Form
* @param graphics Das Grafikobjekt.
*/
protected void fillShape( java.awt.Shape shape, Graphics2D graphics ) {
if( fill != null ) {
graphics.setPaint(fill);
graphics.fill(shape);
} else if( fillColor != null && fillColor.getAlpha() > 0 ) {
graphics.setColor(fillColor.getJavaColor());
graphics.fill(shape);
}
} }
} }

View File

@@ -80,6 +80,17 @@ public abstract class Shape extends FilledShape {
return scale; return scale;
} }
public void setGradient( schule.ngb.zm.Color from, schule.ngb.zm.Color to, Options.Direction dir ) {
Point2D apDir = getAbsAnchorPoint(dir);
Point2D apInv = getAbsAnchorPoint(dir.inverse());
setGradient(apInv.getX(), apInv.getY(), from, apDir.getX(), apDir.getY(), to);
}
public void setGradient( schule.ngb.zm.Color from, schule.ngb.zm.Color to ) {
Point2D ap = getAbsAnchorPoint(CENTER);
setGradient(ap.getX(), ap.getY(), Math.min(ap.getX(), ap.getY()), from, to);
}
public boolean isVisible() { public boolean isVisible() {
return visible; return visible;
} }
@@ -117,6 +128,19 @@ public abstract class Shape extends FilledShape {
} }
} }
/**
* Bestimmt die relativen Koordinaten des angegebenen Ankerpunkt basierend
* auf der angegebenen Breite und Höhe des umschließenden Rechtecks.
* <p>
* Die Koordinaten des Ankerpunkt werden relativ zur oberen linken Ecke des
* Rechtecks mit der Breite {@code width} und der Höhe {@code height}
* bestimmt.
*
* @param width Breite des umschließdenden Rechtecks.
* @param height Höhe des umschließdenden Rechtecks.
* @param anchor Gesuchter Ankerpunkt.
* @return Ein {@link Point2D} mit den relativen Koordinaten.
*/
protected static Point2D.Double getAnchorPoint( double width, double height, Options.Direction anchor ) { protected static Point2D.Double getAnchorPoint( double width, double height, Options.Direction anchor ) {
double wHalf = width * .5, hHalf = height * .5; double wHalf = width * .5, hHalf = height * .5;
@@ -164,14 +188,22 @@ public abstract class Shape extends FilledShape {
} }
/** /**
* Kopiert die Eigenschaften der übergebenen Form in diese. * Kopiert die Eigenschaften der angegebenen Form in diese.
* <p> * <p>
* Unterklassen sollten diese Methode überschreiben, um weitere * Unterklassen sollten diese Methode überschreiben, um weitere
* Eigenschaften zu kopieren (zum Beispiel den Radius eines Kreises). Mit * Eigenschaften zu kopieren (zum Beispiel den Radius eines Kreises).
* dem Aufruf {@code super.copyFrom(shape)} sollten die Basiseigenschaften * Unterklassen sollten immer mit dem Aufruf {@code super.copyFrom(shape)}
* kopiert werden. * die Basiseigenschaften kopieren.
* <p>
* Die Methode sollte so viele Eigenschaften wie möglich von der anderen
* Form in diese kopieren. Wenn die andere Form einen anderen Typ hat, dann
* werden trotzdem die Basiseigenschaften (Konturlinie, Füllung, Position,
* Rotation, Skalierung, Sichtbarkeit und Ankerpunkt) in diese Form kopiert.
* Implementierende Unterklassen können soweit sinnvoll auch andere Werte
* übernehmen. Eine {@link Ellipse} kann beispielsweise auch die Breite und
* Höhe eines {@link Rectangle} übernehmen.
* *
* @param shape * @param shape Die Originalform, von der kopiert werden soll.
*/ */
public void copyFrom( Shape shape ) { public void copyFrom( Shape shape ) {
if( shape != null ) { if( shape != null ) {
@@ -187,6 +219,26 @@ public abstract class Shape extends FilledShape {
} }
} }
/**
* Erzeugt eine Kopie dieser Form mit denselben Eigenschaften.
* <p>
* Unterklassen implementieren diese Methode mit dem genauen Typ der
* Unterklasse. In {@link Rectangle} sieht die Umsetzung beispielsweise so
* aus:
* <pre><code>
* @Override
* public Rectangle copy() {
* return new Rectangle(this);
* }
* </code></pre>
* <p>
* Die Methode kann beliebig umgesetzt werden, um eine 1-zu-1-Kopie dieser
* Form zu erhalten. In der Regel sollte aber jede Form einen Konstruktor
* besitzen, die alle Werte einer andern Form übernimmt. Die gezeigte
* Implementierung dürfte daher im Regelfall ausreichend sein.
*
* @return Eine genaue Kopie dieser Form.
*/
public abstract Shape copy(); public abstract Shape copy();
public abstract java.awt.Shape getShape(); public abstract java.awt.Shape getShape();
@@ -273,7 +325,7 @@ public abstract class Shape extends FilledShape {
} }
public void nextTo( Shape shape, Options.Direction dir ) { public void nextTo( Shape shape, Options.Direction dir ) {
nextTo(shape, dir, STD_BUFFER); nextTo(shape, dir, DEFAULT_BUFFER);
} }
/** /**
@@ -376,6 +428,9 @@ public abstract class Shape extends FilledShape {
} }
Color currentColor = graphics.getColor(); Color currentColor = graphics.getColor();
fillShape(shape, graphics);
strokeShape(shape, graphics);
/*
if( fillColor != null && fillColor.getAlpha() > 0 ) { if( fillColor != null && fillColor.getAlpha() > 0 ) {
graphics.setColor(fillColor.getJavaColor()); graphics.setColor(fillColor.getJavaColor());
graphics.fill(shape); graphics.fill(shape);
@@ -386,6 +441,7 @@ public abstract class Shape extends FilledShape {
graphics.setStroke(createStroke()); graphics.setStroke(createStroke());
graphics.draw(shape); graphics.draw(shape);
} }
*/
graphics.setColor(currentColor); graphics.setColor(currentColor);
} }
} }

View File

@@ -4,21 +4,20 @@ import schule.ngb.zm.Color;
import schule.ngb.zm.Constants; import schule.ngb.zm.Constants;
import schule.ngb.zm.Drawable; import schule.ngb.zm.Drawable;
import schule.ngb.zm.Options; import schule.ngb.zm.Options;
import schule.ngb.zm.util.Noise;
import java.awt.*; import java.awt.BasicStroke;
import java.awt.Shape; import java.awt.Graphics2D;
import java.awt.geom.FlatteningPathIterator; import java.awt.Stroke;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.util.Arrays;
/**
* Basisklasse für Formen, die eine Konturlinie besitzen.
*/
public abstract class StrokedShape extends Constants implements Drawable { public abstract class StrokedShape extends Constants implements Drawable {
protected Color strokeColor = STD_STROKECOLOR; protected Color strokeColor = DEFAULT_STROKECOLOR;
protected double strokeWeight = STD_STROKEWEIGHT; protected double strokeWeight = DEFAULT_STROKEWEIGHT;
protected Options.StrokeType strokeType = SOLID; protected Options.StrokeType strokeType = SOLID;
@@ -80,6 +79,12 @@ public abstract class StrokedShape extends Constants implements Drawable {
this.stroke = null; this.stroke = null;
} }
public void resetStroke() {
setStrokeColor(DEFAULT_STROKECOLOR);
setStrokeWeight(DEFAULT_STROKEWEIGHT);
setStrokeType(SOLID);
}
@Override @Override
public abstract void draw( Graphics2D graphics ); public abstract void draw( Graphics2D graphics );
@@ -118,10 +123,13 @@ public abstract class StrokedShape extends Constants implements Drawable {
return stroke; return stroke;
} }
public void resetStroke() { protected void strokeShape( java.awt.Shape shape, Graphics2D graphics ) {
setStrokeColor(STD_STROKECOLOR); if( strokeColor != null && strokeColor.getAlpha() > 0
setStrokeWeight(STD_STROKEWEIGHT); && strokeWeight > 0.0 ) {
setStrokeType(SOLID); graphics.setColor(strokeColor.getJavaColor());
graphics.setStroke(createStroke());
graphics.draw(shape);
}
} }
} }

View File

@@ -22,7 +22,7 @@ public class Text extends Shape {
protected int width = 0, height = 0, ascent = 0; protected int width = 0, height = 0, ascent = 0;
public Text( double x, double y, String text ) { public Text( double x, double y, String text ) {
this(x, y, text, new Font(Font.SANS_SERIF, Font.PLAIN, STD_FONTSIZE)); this(x, y, text, new Font(Font.SANS_SERIF, Font.PLAIN, DEFAULT_FONTSIZE));
} }
public Text( double x, double y, String text, String fontname ) { public Text( double x, double y, String text, String fontname ) {
super(x, y); super(x, y);
@@ -30,7 +30,7 @@ public class Text extends Shape {
if( userfont != null ) { if( userfont != null ) {
font = userfont; font = userfont;
} else { } else {
font = new Font(Font.SANS_SERIF, Font.PLAIN, STD_FONTSIZE); font = new Font(Font.SANS_SERIF, Font.PLAIN, DEFAULT_FONTSIZE);
} }
setText(text); setText(text);
fillColor = null; fillColor = null;

View File

@@ -336,7 +336,7 @@ public class TurtleLayer extends Layer {
if( strokeColor != null ) { if( strokeColor != null ) {
graphics.setColor(strokeColor.getJavaColor()); graphics.setColor(strokeColor.getJavaColor());
} else { } else {
graphics.setColor(STD_STROKECOLOR.getJavaColor()); graphics.setColor(DEFAULT_STROKECOLOR.getJavaColor());
} }
graphics.fill(shape); graphics.fill(shape);
graphics.setColor(Color.BLACK.getJavaColor()); graphics.setColor(Color.BLACK.getJavaColor());