diff --git a/src/main/java/schule/ngb/zm/Color.java b/src/main/java/schule/ngb/zm/Color.java index 429ef25..c1394a4 100644 --- a/src/main/java/schule/ngb/zm/Color.java +++ b/src/main/java/schule/ngb/zm/Color.java @@ -112,7 +112,7 @@ public class Color implements Paint { } /** - * Erstellt eine graue Farbe entsprechend des Grauwertes gray. + * Erstellt eine graue Farbe entsprechend dem Grauwert {@code gray}. * * @param gray Ein Grauwert zwischen 0 und 255. */ @@ -121,8 +121,8 @@ public class Color implements Paint { } /** - * Erstellt eine graue Farbe entsprechend des Grauwertes gray und - * des Transparentwertes alpha. + * Erstellt eine graue Farbe entsprechend dem Grauwert {@code gray} und dem + * Transparenzwert {@code alpha}. * * @param gray Ein Grauwert zwischen 0 und 255. */ @@ -131,9 +131,9 @@ public class Color implements Paint { } /** - * Erstellt eine Farbe. Die Parameter red, green und - * blue geben die Rot-, Grün- und Blauanteile der Farbe. Die - * Werte liegen zwischen 0 und 255. + * Erstellt eine Farbe. Die Parameter {@code red}, {@code green} und + * {@code blue} geben die Rot-, Grün- und Blauanteile der Farbe. Die Werte + * liegen zwischen 0 und 255. * * @param red Rotwert zwischen 0 und 255. * @param green Grünwert zwischen 0 und 255. @@ -144,11 +144,11 @@ public class Color implements Paint { } /** - * Erstellt eine Farbe. Die Parameter red, green und - * blue geben die Rot-, Grün- und Blauanteile der Farbe. Die - * Werte liegen zwischen 0 und 255. - * alpha gibt den den Transparentwert an (auch zwischen - * 0 und 255), wobei 0 komplett durchsichtig ist und 255 komplett deckend. + * Erstellt eine Farbe. Die Parameter {@code red}, {@code green} und + * {@code blue} geben die Rot-, Grün- und Blauanteile der Farbe. Die Werte + * liegen zwischen 0 und 255. {@code alpha} gibt den den Transparentwert an + * (auch zwischen 0 und 255), wobei 0 komplett durchsichtig ist und 255 + * komplett deckend. * * @param red Rotwert zwischen 0 und 255. * @param green Grünwert zwischen 0 und 255. @@ -160,20 +160,20 @@ public class Color implements Paint { } /** - * Erstellt eine Farbe als Kopie von color. + * Erstellt eine Farbe als Kopie von {@code color}. * - * @param color + * @param color Eine Farbe. */ public Color( Color color ) { this(color.getRGBA(), true); } /** - * Erstellt eine Farbe als Kopie von color und ersetzt den - * Transparentwert durch alpha. + * Erstellt eine Farbe als Kopie von {@code color} und ersetzt den + * Transparentwert durch {@code alpha}. * - * @param color - * @param alpha + * @param color Eine Farbe. + * @param alpha Der neue Transparenzwert. */ public Color( Color color, int alpha ) { this(color.getRed(), color.getGreen(), color.getBlue(), alpha); @@ -208,18 +208,51 @@ public class Color implements Paint { /** * Erzeugt eine Farbe aus einem kodierten RGBA Integer-Wert. + *
+ * Der 32-bit Integer enthält (von rechts) in Bit 1 bis 8 den Rotwert, in + * Bit 9 bis 16 Grünwert, in Bit 17 bis 24 den Blauwert und in Bit 25 bis 32 + * den Transparenzwert der Farbe. * - * @param rgba - * @return + * @param rgba Eine RGBA-Farbe. + * @return Ein Farbobjekt. */ public static Color getRGBColor( int rgba ) { return new Color(rgba, true); } + /** + * Erzeugt eine Farbe aus Werten im + * HSB-Farbraum. + *
+ * {code h} beschreibt den Farbwert (engl. hue), {@code s} die + * Sättigung (engl. saturation) und {@code b} die absolute + * Helligkeit (engl. brightness) der Farbe. Alle Werte werden + * zwischen 0.0 und 1.0 angegeben. + * + * @param h Der Farbwert. + * @param s Die Sättigung. + * @param b Die absolute Helligkeit. + * @return Ein Farbobjekt. + * @see java.awt.Color#getHSBColor(float, float, float) + */ public static Color getHSBColor( double h, double s, double b ) { return new Color(java.awt.Color.getHSBColor((float) h, (float) s, (float) b)); } + /** + * Erzeugt eine Farbe aus Werten im + * HSL-Farbraum. + *
+ * {code h} beschreibt den Farbwert (engl. hue), {@code s} die + * Sättigung (engl. saturation) und {@code l} die relative + * Helligkeit (engl. lightness) der Farbe. Alle Werte werden + * zwischen 0.0 und 1.0 angegeben. + * + * @param h Der Farbwert. + * @param s Die Sättigung. + * @param l Die relative Helligkeit. + * @return Ein Farbobjekt. + */ public static Color getHSLColor( double h, double s, double l ) { int rgb = Color.HSLtoRGB(new float[]{(float) h, (float) s, (float) l}); return Color.getRGBColor(rgb); @@ -259,12 +292,16 @@ public class Color implements Paint { } /** - * Erzeugt eine Farbe aus einem hexadezimalen Code. Der Hexcode kann sechs- - * oder achtstellig sein (wenn ein Transparentwert vorhanden ist). Dem Code - * kann ein {@code #} Zeichen vorangestellt sein. + * Erzeugt eine Farbe aus einem hexadezimalen Code. Der Hexcode kann drei-, + * sechs- oder achtstellig sein (wenn ein Transparentwert vorhanden ist). + * Dem Code kann ein {@code #} Zeichen vorangestellt sein, muss es aber + * nicht. + *
+ * Bei einem dreistelligen Code wird jedes zeichen doppelt interpretiert. + * Das beduetet {@code #ABC} ist gleichbedeutend mit {@code #AABBCC}. * - * @param hexcode - * @return + * @param hexcode Eine Farbe als Hexcode. + * @return Ein Farbobjekt. */ public static Color parseHexcode( String hexcode ) { if( hexcode.startsWith("#") ) { @@ -301,7 +338,7 @@ public class Color implements Paint { if( color1 == null && color2 == null ) { throw new IllegalArgumentException("Color.interpolate() needs at least one color to be not null."); } - if( t < 0.0 || color2 == null ) { + if( (color1 != null && t < 0.0) || color2 == null ) { return color1.copy(); } if( t > 1.0 || color1 == null ) { @@ -351,6 +388,14 @@ public class Color implements Paint { return hsl; } + /** + * Konvertiert die Komponenten einer Farbe aus dem HSL-Farbraum in den + * RGB-Farbraum. + * + * @param hsl Die HSL-Komponenten als float-Array. + * @return Der RGBA-Farbwert. + * @see #HSLtoRGB(float[], int) + */ public static int HSLtoRGB( float[] hsl ) { return HSLtoRGB(hsl, 255); } @@ -359,9 +404,9 @@ public class Color implements Paint { * Konvertiert eine Farbe mit Komponenten im HSL-Farbraum in den * RGB-Farbraum. *
- * Die Farbkomponenten werden als Float-Array übergeben. Im Index 0 steht - * der h-Wert im Bereich 0 bis 360, Index 1 und 2 enthalten den s- und - * l-Wert im Bereich von 0 bis 1. + * Die Farbkomponenten werden als float-Array übergeben. Im Index 0 steht + * der H-Wert im Bereich 0 bis 360, Index 1 und 2 enthalten den S- und + * L-Wert im Bereich von 0 bis 1. * * @param hsl Die Farbkomponenten im HSL-Farbraum. * @param alpha Ein Transparenzwert im Bereich 0 bis 255. @@ -506,10 +551,11 @@ public class Color implements Paint { /** * Prüft, ob ein anderes Objekt zu diesem gleich ist. + *
+ * Die Methode gibt genau dann {@code true} zurück, wenn das andere Objekt + * nicht {@code null} ist, vom Typ {@code Color} ist und es dieselben Rot-, + * Grün-, Blau- und Transparenzwerte hat. * - * Die Methode gibt genau dann {@code true} zurück, wenn das andere - * Objekt nicht {@code null} ist, vom Typ {@code Color} ist und es - * dieselben Rot-, Grün-, Blau- und Transparenzwerte hat. * @param obj Das zu vergleichende Objekt. * @return {@code true}, wenn die Objekte gleich sind, sonst {@code false}. */ diff --git a/src/main/java/schule/ngb/zm/Constants.java b/src/main/java/schule/ngb/zm/Constants.java index 3dc9fa6..63a1cc9 100644 --- a/src/main/java/schule/ngb/zm/Constants.java +++ b/src/main/java/schule/ngb/zm/Constants.java @@ -1054,7 +1054,7 @@ public class Constants { } /** - * Ermittelt den Arkuskosinus der angegebenen Zahl. + * Ermittelt den Arcuskosinus der angegebenen Zahl. * * @param x Eine Zahl. * @return {@code acos(x)}. @@ -1064,7 +1064,7 @@ public class Constants { } /** - * Ermittelt den Arkusktangens der angegebenen Zahl. + * Ermittelt den Arcusktangens der angegebenen Zahl. * * @param x Eine Zahl. * @return {@code atan(x)}. @@ -1681,38 +1681,93 @@ public class Constants { } } + /** + * Konvertiert einen char-Wert in einen double-Wert. + * + * @param value Der char-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( char value ) { return value; } + /** + * Konvertiert einen byte-Wert in einen double-Wert. + * + * @param value Der byte-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( byte value ) { return value; } + /** + * Konvertiert einen short-Wert in einen double-Wert. + * + * @param value Der short-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( short value ) { return value; } + /** + * Konvertiert einen long-Wert in einen double-Wert. + * + * @param value Der long-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( long value ) { return (double) value; } + /** + * Konvertiert einen double-Wert in einen double-Wert. + * + * @param value Der double-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( double value ) { return value; } + /** + * Konvertiert einen float-Wert in einen double-Wert. + * + * @param value Der float-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( float value ) { return value; } + /** + * Konvertiert einen int-Wert in einen double-Wert. + * + * @param value Der int-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( int value ) { return value; } + /** + * Konvertiert einen boolean-Wert in einen double-Wert. + * + * @param value Der boolean-Wert. + * @return Ein double-Wert. + */ public static final double asDouble( boolean value ) { return value ? 1.0 : 0.0; } + /** + * Konvertiert einen String in einen double-Wert. + * + * @param value Der String. + * @return Ein double-Wert. + * @see Double#parseDouble(String) + */ public static final double asDouble( String value ) { try { return Double.parseDouble(value); @@ -1721,38 +1776,93 @@ public class Constants { } } + /** + * Konvertiert einen char-Wert in einen boolean-Wert. + * + * @param value Der char-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( char value ) { return value != 0; } + /** + * Konvertiert einen byte-Wert in einen boolean-Wert. + * + * @param value Der byte-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( byte value ) { return value != 0; } + /** + * Konvertiert einen short-Wert in einen boolean-Wert. + * + * @param value Der short-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( short value ) { return value != 0; } + /** + * Konvertiert einen int-Wert in einen boolean-Wert. + * + * @param value Der int-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( int value ) { return value != 0; } + /** + * Konvertiert einen long-Wert in einen boolean-Wert. + * + * @param value Der long-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( long value ) { return value != 0L; } + /** + * Konvertiert einen double-Wert in einen boolean-Wert. + * + * @param value Der double-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( double value ) { return value != 0.0; } + /** + * Konvertiert einen float-Wert in einen boolean-Wert. + * + * @param value Der float-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( float value ) { return value != 0.0f; } + /** + * Konvertiert einen boolean-Wert in einen boolean-Wert. + * + * @param value Der boolean-Wert. + * @return Ein boolean-Wert. + */ public static final boolean asBool( boolean value ) { return value; } + /** + * Konvertiert einen String in einen boolean-Wert. + * + * @param value Der String. + * @return Ein boolean-Wert. + * @see Boolean#parseBoolean(String) + */ public static final boolean asBool( String value ) { return Boolean.parseBoolean(value); } @@ -1813,7 +1923,7 @@ public class Constants { return Integer.valueOf(binary, 16); } - // Konstants für Key events (Copied from KeyEvent) + // Konstanten für Key events (Copied from KeyEvent) /** * Constant for the ENTER virtual key. diff --git a/src/main/java/schule/ngb/zm/Layer.java b/src/main/java/schule/ngb/zm/Layer.java index f59a985..5946e85 100644 --- a/src/main/java/schule/ngb/zm/Layer.java +++ b/src/main/java/schule/ngb/zm/Layer.java @@ -12,10 +12,10 @@ import java.awt.image.BufferedImage; * Die {@code Zeichenleinwand} besteht aus einer Reihe von Ebenen, die * übereinandergelegt und von "unten" nach "oben" gezeichnet werden. Die Inhalte * der oberen Ebenen können also Inhalte der darunterliegenden verdecken. - * - * Ebenen sind ein zentraler Bestandteil bei der Implementierung einer {@link Zeichenmaschine}. - * Es werden - * Sie erben von {@code Constants}, damit sie beim + *
+ * Ebenen sind ein zentraler Bestandteil bei der Implementierung einer + * {@link Zeichenmaschine}. Sie erben von {@code Constants}, da neue Ebenentypen + * von Nutzern implementiert werden können. */ public abstract class Layer extends Constants implements Drawable, Updatable { @@ -43,24 +43,39 @@ public abstract class Layer extends Constants implements Drawable, Updatable { protected boolean active = true; + /** + * Erstellt eine neue Ebene mit den Standardmaßen. + */ public Layer() { this(DEFAULT_WIDTH, DEFAULT_HEIGHT); } + /** + * Erstellt eine neue Ebene mit den angegebenen Maßen. + * + * @param width Die Breite der Ebene. + * @param height Die Höhe der Ebene. + */ public Layer( int width, int height ) { createCanvas(width, height); } + /** + * @return Die Breite der Ebene. + */ public int getWidth() { return buffer.getWidth(); } + /** + * @return Die Höhe der Ebene. + */ public int getHeight() { return buffer.getHeight(); } /** - * Ändert die Größe der Ebene auf die angegebene Größe. + * Ändert die Größe der Ebene auf die angegebenen Maße. * * @param width Die neue Breite. * @param height Die neue Höhe. @@ -88,7 +103,7 @@ public abstract class Layer extends Constants implements Drawable, Updatable { /** * Erstellt einen neuen Puffer für die Ebene und konfiguriert diesen. * - * @param width Width des neuen Puffers. + * @param width Breite des neuen Puffers. * @param height Höhe des neuen Puffers. */ private void createCanvas( int width, int height ) { @@ -115,7 +130,7 @@ public abstract class Layer extends Constants implements Drawable, Updatable { * Erstellt einen neuen Puffer für die Ebene mit der angegebenen Größe und * kopiert den Inhalt des alten Puffers in den Neuen. * - * @param width Width des neuen Puffers. + * @param width Breite des neuen Puffers. * @param height Höhe des neuen Puffers. */ private void recreateCanvas( int width, int height ) { @@ -155,14 +170,26 @@ public abstract class Layer extends Constants implements Drawable, Updatable { return visible; } + /** + * Versteckt die Ebene. + */ public void hide() { visible = false; } - public void view() { + /** + * Zeigt die Ebene an, falls sie versteckt war. + */ + @SuppressWarnings("unused") + public void show() { visible = true; } + /** + * Versteckt oder zeigt die Ebene, je nachdem, welchen Zustand sie derzeit + * hat. + */ + @SuppressWarnings("unused") public void toggle() { visible = !visible; } diff --git a/src/main/java/schule/ngb/zm/Options.java b/src/main/java/schule/ngb/zm/Options.java index 0e3370c..d170a87 100644 --- a/src/main/java/schule/ngb/zm/Options.java +++ b/src/main/java/schule/ngb/zm/Options.java @@ -11,17 +11,71 @@ public final class Options { private Options() { } + /** + * Linienstile für Konturlinien. + */ public enum StrokeType { - SOLID, DASHED, DOTTED + /** + * Durchgezogene Linien. + */ + SOLID, + + /** + * Getrichelte Linien. + */ + DASHED, + + /** + * Gepunktete Linien. + */ + DOTTED } + /** + * Stile für Pfeilspitzen. + */ public enum ArrowHead { - LINES, FILLED + /** + * Einfache Pfeilspitze aus zwei Linien. + */ + LINES, + + /** + * Gefülltes Dreieck. + */ + FILLED } + /** + * Arten von Bögen. + *
+ * Die Werte legen fest, wie Bögen geschlossen werden sollen, wenn sie + * beispielsweise gefüllt werden. + *
+ * Wrapper für die AWT-Konstanten in {@link Arc2D}. + */ public enum PathType { - OPEN(Arc2D.OPEN), CLOSED(Arc2D.CHORD), PIE(Arc2D.PIE); + /** + * Offener Pfad, bei dem die Pfadenden direkt miteinander verbunden + * werden ohne eine Linie zu ziehen. + */ + OPEN(Arc2D.OPEN), + /** + * Geschlossener Pfad, bei dem die Pfadenden direkt miteinander + * verbunden werden, indem eine Linie gezogen wird. + */ + CLOSED(Arc2D.CHORD), + + /** + * Geschlossener Pfad, bei dem Linien von den Pfadenden zum Mittelpunkt + * des Kreises, der den Kreisbogen festlegt, gezogen werden. + */ + PIE(Arc2D.PIE); + + /** + * Der entsprechende Wert der Konstanten in {@link Arc2D} + */ public final int awt_type; PathType( int type ) { @@ -33,25 +87,100 @@ public final class Options { * Zustände in denen sich die Zeichenmaschine befinden kann. */ public enum AppState { + /** + * Die Zeichenmaschine befindet sich in der Initialisierung. Die + * Laufzeitumgebung wird konfiguriert und alle nötigen Komonenten + * ({@link Zeichenfenster}, {@link Zeichenleinwand}, ...) werden + * erstellt. + */ INITIALIZING, + + /** + * Die Initialisierung der Zeichenmaschine ist beendet, aber der + * {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * wurde noch nicht gestartet. + */ INITIALIZED, + + /** + * Die Zeichenmaschine wurde gestartet und der + * {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * arbeitet. + */ RUNNING, + + /** + * Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * wurde pausiert. + */ PAUSED, + + /** + * Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * wurde gestoppt, die Zeichenmaschine ist aber noch nicht vollständig + * heruntergefahren und hat noch nicht alle Ressourcen freigegeben. + */ STOPPED, + + /** + * Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * ist beendet. + */ TERMINATED, + + /** + * Die Zeichenmaschine ist dabei, vollständig herunterzufahren und alle + * Ressourcen freizugeben. + */ QUITING, + + /** + * Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread} + * wartet gerade auf den nächsten Frame. + */ IDLE, + + /** + * Die Zeichenmaschine führt gerade + * {@link Zeichenmaschine#update(double)} aus. + */ UPDATING, + + /** + * Die Zeichenmaschine führt gerade {@link Zeichenmaschine#draw()} aus. + */ DRAWING, + + /** + * Die Ausführung der Zeichenmaschine wurde mit + * {@link Zeichenmaschine#delay(int)} verzögert und wartet auf + * Fortsetzung. + */ DELAYED, + + /** + * Die Zeichenmaschine sendet gereade gesammelte Events und führt Tasks + * aus. + */ DISPATCHING } /** * Richtungen für die Ausrichtung von Formen. Richtungen sind durch - * Einheitsvektoren bzw. deren Kombination repräsentiert, wodurch mit ihnen - * gerechnet werden kann. Jede Richtung ist zusätzlich als Himmelsrichtung - * definiert. + * Einheitsvektoren bzw. deren Kombination im Koordinatensystem der + * Zeichenfläche repräsentiert, wodurch mit ihnen gerechnet werden kann. Die + * Richtung {@link #DOWN} ist beispielsweise gleich {@code (1, 0)}. + *
+ * Jede Richtung ist zusätzlich als Himmelsrichtung definiert. {@link #EAST} + * ist äquivalent zu {@link #RIGHT} als {@code (0, 1)} definiert. Auch wenn + * beide Werte dieselbe Richtung beschreiben sind sie nicht "gleich" + * ({@code EAST != RIGHT}). Um verschiedene Richtungen zuverlässig zu + * vergleichen, sollte daher {@link #equals(Direction)} verwendet werden. + *
+ * Für zusammengesetzten Richtungen wie {@link #NORTHEAST} bzw + * {@link #UPRIGHT} lassen sich mit {@link #in(Direction)} und + * {@link #contains(Direction)} Beziehungen zu den anderen Richtungen + * prüfen. Beispielsweise ist {@code NORTHEAST.contains(NORTH)} wahr. */ public enum Direction { CENTER(0, 0), @@ -89,30 +218,116 @@ public final class Options { this.y = original.y; } + /** + * Prüft, ob die angegebene Richtung gleich dieser ist. Dabei werden die + * Komponenten des Richtungsvektors geprüft. Daher sind für die Methode + * beispielsweise {@link #NORTH} und {@link #UP} gleich. + * + * @param dir Eine andere Richtung. + * @return {@code true}, wenn die Richtungen dieselben Komponenten + * haben, {@code false} sonst. + */ + public boolean equals( Direction dir ) { + return this.x == dir.x && this.y == dir.y; + } + + /** + * Prüft, ob diese Richtung Tile der angegebenen Richtung ist. + *
+ * Beispielsweise ist {@link #NORTH} Teil von {@link #NORTHWEST}, aber + * nicht von {@link #SOUTHWEST}. Dabei wird doe Art der Richtung nicht + * beachtet. {@link #UP} ist daher auch Teil von {@link #NORTHWEST}. + * + *
+ * NORTH.in(NORTHWEST) // true + * NORTH.in(SOUTHWEST) // false + * UP.in(NORTHWEST) // true + *+ * + * @param dir Eine andere Richtung. + * @return {@code true}, wenn diese Richtungen Teil der anderen ist, + * {@code false} sonst. + */ public boolean in( Direction dir ) { return (this.x == dir.x && this.y == 0) || (this.y == dir.y && this.x == 0) || (this.x == dir.x && this.y == dir.y); } + /** + * Prüft, ob die angegebene Richtung Teil dieser Richtung ist. + *
+ * Beispielsweise ist {@link #NORTH} Teil von {@link #NORTHWEST}, aber + * nicht von {@link #SOUTHWEST}. Dabei wird die Art der Richtung nicht + * beachtet. {@link #UP} ist daher auch Teil von {@link #NORTHWEST}. + * + *
+ * NORTHWEST.contains(NORTH) // true + * SOUTHWEST.in(NORTH) // false + * NORTHWEST.in(UP) // true + *+ * + * @param dir Eine andere Richtung. + * @return {@code true}, wenn diese Richtungen Teil der anderen ist, + * {@code false} sonst. + */ public boolean contains( Direction dir ) { return dir.in(this); } + /** + * @return Diese Richtung als Vektor-Objekt. + */ public Vector asVector() { return new Vector(x, y); } /** - * Gibt die entgegengesetzte Richtung zu dieser zurück. + * Liefert die entgegengesetzte Richtung zu dieser. + *
+ * Es wird die Art der Richtung berücksichtigt. Das bedeutet, das + * Inverse von {@link #UP} ist {@link #DOWN}, während das Inverse von + * {@link #NORTH} zu {@link #SOUTH} wird. * - * @return + * @return Die entgegengesetzte Richtung zu dieser. */ public Direction inverse() { - for( Direction dir : Direction.values() ) { - if( dir.x == -this.x && dir.y == -this.y ) { - return dir; - } + switch( this ) { + case UP: + return DOWN; + case DOWN: + return UP; + case LEFT: + return RIGHT; + case RIGHT: + return LEFT; + case UPLEFT: + return DOWNRIGHT; + case UPRIGHT: + return DOWNLEFT; + case DOWNLEFT: + return UPRIGHT; + case DOWNRIGHT: + return UPLEFT; + case MIDDLE: + return MIDDLE; + case NORTH: + return SOUTH; + case SOUTH: + return NORTH; + case EAST: + return WEST; + case WEST: + return EAST; + case SOUTHWEST: + return NORTHEAST; + case SOUTHEAST: + return NORTHWEST; + case NORTHEAST: + return SOUTHWEST; + case NORTHWEST: + return SOUTHEAST; + default: + return CENTER; } - return CENTER; } } diff --git a/src/main/java/schule/ngb/zm/Strokeable.java b/src/main/java/schule/ngb/zm/Strokeable.java index 48db51f..36b0e29 100644 --- a/src/main/java/schule/ngb/zm/Strokeable.java +++ b/src/main/java/schule/ngb/zm/Strokeable.java @@ -15,7 +15,7 @@ import java.awt.Stroke; * {@link Strokeable#setStrokeColor(Color, int)} Methode hat, dann sollte auch * eine {@link schule.ngb.zm.layers.TurtleLayer.Turtle} dieselbe Methode * anbieten. Im Einzelfall kann es sinnvoll sein, weitere Methoden für - * Konturlinien zur erfügung zu stellen. Allerdings sollte davon nach + * Konturlinien zur verfügung zu stellen. Allerdings sollte davon nach * Möglichkeit zugunsten einer einheitlichen API abgesehen werden. *
* Das Äquivalent für Füllungen stellt {@link Fillable} dar. diff --git a/src/main/java/schule/ngb/zm/Updatable.java b/src/main/java/schule/ngb/zm/Updatable.java index 94eb76e..c519626 100644 --- a/src/main/java/schule/ngb/zm/Updatable.java +++ b/src/main/java/schule/ngb/zm/Updatable.java @@ -28,7 +28,7 @@ public interface Updatable { * @return {@code true}, wenn das Objekt aktiv ist, {@code false} * andernfalls. */ - public boolean isActive(); + boolean isActive(); /** * Änderung des Zustandes des Objekts abhängig vom Zeitintervall @@ -39,6 +39,6 @@ public interface Updatable { * * @param delta Zeitintervall seit dem letzten Aufruf (in Sekunden). */ - public void update( double delta ); + void update( double delta ); } diff --git a/src/main/java/schule/ngb/zm/Vector.java b/src/main/java/schule/ngb/zm/Vector.java index 5ea67c2..67f3aaa 100644 --- a/src/main/java/schule/ngb/zm/Vector.java +++ b/src/main/java/schule/ngb/zm/Vector.java @@ -422,8 +422,8 @@ public class Vector extends Point2D.Double { * dem quadrierten Abstand durchführen, wenn auch die gewünschte Entfernung * quadriert wird. * - * @param vector - * @return + * @param vector Ein anderer Vektor. + * @return Das Quadrat der Entfernung zum anderen Vektor. */ public double distanceSq( Vector vector ) { return super.distanceSq(vector); diff --git a/src/main/java/schule/ngb/zm/Zeichenfenster.java b/src/main/java/schule/ngb/zm/Zeichenfenster.java index 95f28ef..2e6fb87 100644 --- a/src/main/java/schule/ngb/zm/Zeichenfenster.java +++ b/src/main/java/schule/ngb/zm/Zeichenfenster.java @@ -9,9 +9,7 @@ import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; -import java.io.File; import java.io.IOException; -import java.lang.reflect.Method; import java.net.URL; import java.util.ArrayList; @@ -25,6 +23,12 @@ import java.util.ArrayList; */ public class Zeichenfenster extends JFrame { + /** + * Setzt das Look and Feel auf den Standard des Systems. + *
+ * Sollte einmalig vor erstellen des erstyen Programmfensters aufgerufen
+ * werden.
+ */
public static final void setLookAndFeel() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
@@ -33,6 +37,17 @@ public class Zeichenfenster extends JFrame {
}
}
+ /**
+ * Ermittelt ein {@link GraphicsDevice Anzeigegerät}, auf dem ein neues
+ * Zeichenfenster angezeigt werden soll. In der Regel ist dies der
+ * Bildschirm, auf dem sich derzeit der Mauszeiger befindet. Kann kein
+ * solcher Bildschirm ermittelt werden, wird das
+ * {@link GraphicsEnvironment#getDefaultScreenDevice() Standardgerät}
+ * zurückgegeben.
+ *
+ * @return Das Anzeigegerät, auf dem ein neues Fenster angezeigt werden
+ * sollte.
+ */
public static final GraphicsDevice getGraphicsDevice() {
// Wir suchen den Bildschirm, der derzeit den Mauszeiger enthält, um
// das Zeichenfenster dort zu zentrieren.
@@ -55,10 +70,10 @@ public class Zeichenfenster extends JFrame {
}
/**
- * Das Anzeigefenster, auf dem die ZM gestartet wurde (muss nicht gleich dem
- * Aktuellen sein, wenn das Fenster verschoben wurde).
+ * Das Anzeigegerät, auf dem die Zeichenmaschine gestartet wurde (muss nicht
+ * gleich dem Aktuellen sein, wenn das Fenster verschoben wurde).
*/
- private GraphicsDevice displayDevice;
+ private final GraphicsDevice displayDevice;
/**
* Bevorzugte Abmessungen der Zeichenleinwand. Für das Zeichenfenster hat es
@@ -90,20 +105,56 @@ public class Zeichenfenster extends JFrame {
}
};
- private Zeichenleinwand canvas;
+ // Die Zeichenleinwand dieses Fensters.
+ private final Zeichenleinwand canvas;
+ /**
+ * Erstellt ein neues Zeichenfenster mit dem angegebenen Titel und einer
+ * {@link Zeichenleinwand} in der angegebenen Größe.
+ *
+ * @param width Die Breite der Zeichenleinwand.
+ * @param height Die Höhe der Zeichenleinwand.
+ * @param title Der Titel des Fensters.
+ */
+ @SuppressWarnings( "unused" )
public Zeichenfenster( int width, int height, String title ) {
this(new Zeichenleinwand(width, height), title, getGraphicsDevice());
}
+ /**
+ * Erstellt ein neues Zeichenfenster mit dem angegebenen Titel und einer
+ * {@link Zeichenleinwand} in der angegebenen Größe auf dem angegebenen
+ * Anzeigegerät.
+ *
+ * @param width Die Breite der Zeichenleinwand.
+ * @param height Die Höhe der Zeichenleinwand.
+ * @param title Der Titel des Fensters.
+ * @param displayDevice Das Anzeigegerät für das Fenster.
+ */
+ @SuppressWarnings( "unused" )
public Zeichenfenster( int width, int height, String title, GraphicsDevice displayDevice ) {
this(new Zeichenleinwand(width, height), title, displayDevice);
}
+ /**
+ * Erstellt ein neues Zeichenfenster mit dem angegebenen Titel und der
+ * angegebene {@link Zeichenleinwand}.
+ *
+ * @param canvas Die Zeichenleinwand.
+ * @param title Der Titel des Fensters.
+ */
public Zeichenfenster( Zeichenleinwand canvas, String title ) {
this(canvas, title, getGraphicsDevice());
}
+ /**
+ * Erstellt ein neues Zeichenfenster mit dem angegebenen Titel und der
+ * angegebene {@link Zeichenleinwand} auf dem angegebenen Anzeigegerät.
+ *
+ * @param canvas Die Zeichenleinwand.
+ * @param title Der Titel des Fensters.
+ * @param displayDevice Das Anzeigegerät für das Fenster.
+ */
public Zeichenfenster( Zeichenleinwand canvas, String title, GraphicsDevice displayDevice ) {
super(Validator.requireNotNull(displayDevice).getDefaultConfiguration());
this.displayDevice = displayDevice;
@@ -124,14 +175,19 @@ public class Zeichenfenster extends JFrame {
try {
if( Zeichenmaschine.MACOS ) {
URL iconUrl = Zeichenmaschine.class.getResource("icon_512.png");
- Image icon = ImageIO.read(iconUrl);
- // Dock Icon in macOS setzen
- Taskbar taskbar = Taskbar.getTaskbar();
- taskbar.setIconImage(icon);
+ if( iconUrl != null ) {
+ Image icon = ImageIO.read(iconUrl);
+ // Dock Icon in macOS setzen
+ Taskbar taskbar = Taskbar.getTaskbar();
+ taskbar.setIconImage(icon);
+ }
} else {
ArrayList
+ * Das Anzeigegerät muss nicht unbedingt gleich dem sein, auf dem sich das
+ * Fenster derzeit befindet, wenn das Fenster verschoben wurde.
+ *
+ * @return Das Anzeigegerät.
+ */
+ @SuppressWarnings( "unused" )
public GraphicsDevice getDisplayDevice() {
return displayDevice;
}
+ /**
+ * Liefert die Abmessungen des Anzeigegeräts, auf dem das Fenster gestartet
+ * wurde.
+ *
+ * @return Die Abmessungen des Anzeigegeräts.
+ */
public Rectangle getScreenBounds() {
// return GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
return displayDevice.getDefaultConfiguration().getBounds();
}
+ /**
+ * Liefert die Zeichenleinwand dieses Fensters.
+ *
+ * @return Die Zeichenleinwand.
+ */
+ @SuppressWarnings( "unused" )
public Zeichenleinwand getCanvas() {
return canvas;
}
+ /**
+ * Liefert die Abmessungen der Zeichenleinwand zurück.
+ *
+ * @return Die Abmessungen der Zeichenleinwand.
+ */
public Rectangle getCanvasBounds() {
return canvas.getBounds();
}
@@ -179,6 +261,12 @@ public class Zeichenfenster extends JFrame {
);
}
+ /**
+ * Setzt die Größe der Zeichenleinwand auf die angegebenen Werte.
+ *
+ * @param newWidth Neue Breite der Zeichenleinwand.
+ * @param newHeight Neue Höhe der Zeichenleinwand.
+ */
public void setCanvasSize( int newWidth, int newHeight ) {
// TODO: (ngb) Put constrains on max/min frame/canvas size
if( fullscreen ) {
@@ -259,6 +347,12 @@ public class Zeichenfenster extends JFrame {
}
}
+ /**
+ * Prüft, ob sich dieses Zeichenfenster im Vollbild befindet.
+ *
+ * @return {@code true}, wenn das Fenster im Vollbild ist, {@code false}
+ * sonst.
+ */
public boolean isFullscreen() {
Window win = displayDevice.getFullScreenWindow();
return fullscreen && win.equals(this);
diff --git a/src/main/java/schule/ngb/zm/Zeichenleinwand.java b/src/main/java/schule/ngb/zm/Zeichenleinwand.java
index c2eaf72..f46ef1e 100644
--- a/src/main/java/schule/ngb/zm/Zeichenleinwand.java
+++ b/src/main/java/schule/ngb/zm/Zeichenleinwand.java
@@ -1,6 +1,5 @@
package schule.ngb.zm;
-import schule.ngb.zm.layers.ColorLayer;
import schule.ngb.zm.util.Log;
import java.awt.Canvas;
@@ -8,7 +7,10 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
/**
* Eine Leinwand ist die Hauptkomponente einer Zeichenmaschine. Sie besteht aus
@@ -22,13 +24,13 @@ import java.util.*;
*/
public class Zeichenleinwand extends Canvas {
+ // Lokales Lock für Rendervorgänge.
private final Object[] renderLock = new Object[0];
- /**
- * Liste der hinzugefügten Ebenen.
- */
+ // Liste der hinzugefügten Ebenen.
private final List
* Die Konstanten der Klasse {@link Cursor} definieren 13 Standardzeiger,
* die durch angabe der Nummer geladen werden können.
- *
- * DrawingLayer draw = getLayer(DrawingLayer.class);
- *
+ *
*
* @param layerClass
* @param
+ * DrawingLayer draw = getLayer(DrawingLayer.class);
+ *
- * setCursor(Cursor.HAND_CURSOR);
- *
+ *
*
* @param pPredefinedCursor Eine der Cursor-Konstanten.
* @see Cursor
@@ -1022,9 +1022,9 @@ public class Zeichenmaschine extends Constants {
* {@code delta} wird in Sekunden angegeben. Um eine Form zum Beispiel um
* {@code 50} Pixel pro Sekunde in {@code x}-Richtung zu bewegen, kann so
* vorgegangen werden:
- *
+ * setCursor(Cursor.HAND_CURSOR);
+ *
+ *
*
* @param delta
*/
diff --git a/src/main/java/schule/ngb/zm/util/io/FileLoader.java b/src/main/java/schule/ngb/zm/util/io/FileLoader.java
index 4454476..17fc59e 100644
--- a/src/main/java/schule/ngb/zm/util/io/FileLoader.java
+++ b/src/main/java/schule/ngb/zm/util/io/FileLoader.java
@@ -30,7 +30,7 @@ public final class FileLoader {
}
/**
- * Lädt die angegebene Datei Zeilenweise in ein Array.
+ * Lädt die angegebene Datei Zeilenweise in eine Liste.
*
* @param source
* @param charset
@@ -161,7 +161,7 @@ public final class FileLoader {
).toArray(double[][]::new);
}
- public FileLoader() {
+ private FileLoader() {
}
private static final Log LOG = Log.getLogger(FileLoader.class);
+ *
* shape.move(50*delta, 0.0);
- *