mirror of
https://github.com/jneug/zeichenmaschine.git
synced 2026-04-14 06:33:34 +02:00
Einige Bugfixes und Verbesserungen und ganz viel Doku
This commit is contained in:
@@ -112,7 +112,7 @@ public class Color implements Paint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt eine graue Farbe entsprechend des Grauwertes <var>gray</var>.
|
* Erstellt eine graue Farbe entsprechend dem Grauwert {@code gray}.
|
||||||
*
|
*
|
||||||
* @param gray Ein Grauwert zwischen 0 und 255.
|
* @param gray Ein Grauwert zwischen 0 und 255.
|
||||||
*/
|
*/
|
||||||
@@ -121,8 +121,8 @@ public class Color implements Paint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt eine graue Farbe entsprechend des Grauwertes <var>gray</var> und
|
* Erstellt eine graue Farbe entsprechend dem Grauwert {@code gray} und dem
|
||||||
* des Transparentwertes <var>alpha</var>.
|
* Transparenzwert {@code alpha}.
|
||||||
*
|
*
|
||||||
* @param gray Ein Grauwert zwischen 0 und 255.
|
* @param gray Ein Grauwert zwischen 0 und 255.
|
||||||
*/
|
*/
|
||||||
@@ -131,9 +131,9 @@ public class Color implements Paint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt eine Farbe. Die Parameter <var>red</var>, <var>green</var> und
|
* Erstellt eine Farbe. Die Parameter {@code red}, {@code green} und
|
||||||
* <var>blue</var> geben die Rot-, Grün- und Blauanteile der Farbe. Die
|
* {@code blue} geben die Rot-, Grün- und Blauanteile der Farbe. Die Werte
|
||||||
* Werte liegen zwischen 0 und 255.
|
* liegen zwischen 0 und 255.
|
||||||
*
|
*
|
||||||
* @param red Rotwert zwischen 0 und 255.
|
* @param red Rotwert zwischen 0 und 255.
|
||||||
* @param green Grünwert 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 <var>red</var>, <var>green</var> und
|
* Erstellt eine Farbe. Die Parameter {@code red}, {@code green} und
|
||||||
* <var>blue</var> geben die Rot-, Grün- und Blauanteile der Farbe. Die
|
* {@code blue} geben die Rot-, Grün- und Blauanteile der Farbe. Die Werte
|
||||||
* Werte liegen zwischen 0 und 255.
|
* liegen zwischen 0 und 255. {@code alpha} gibt den den Transparentwert an
|
||||||
* <var>alpha</var> gibt den den Transparentwert an (auch zwischen
|
* (auch zwischen 0 und 255), wobei 0 komplett durchsichtig ist und 255
|
||||||
* 0 und 255), wobei 0 komplett durchsichtig ist und 255 komplett deckend.
|
* komplett deckend.
|
||||||
*
|
*
|
||||||
* @param red Rotwert zwischen 0 und 255.
|
* @param red Rotwert zwischen 0 und 255.
|
||||||
* @param green Grünwert 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 <var>color</var>.
|
* Erstellt eine Farbe als Kopie von {@code color}.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color Eine Farbe.
|
||||||
*/
|
*/
|
||||||
public Color( Color color ) {
|
public Color( Color color ) {
|
||||||
this(color.getRGBA(), true);
|
this(color.getRGBA(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erstellt eine Farbe als Kopie von <var>color</var> und ersetzt den
|
* Erstellt eine Farbe als Kopie von {@code color} und ersetzt den
|
||||||
* Transparentwert durch <var>alpha</var>.
|
* Transparentwert durch {@code alpha}.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color Eine Farbe.
|
||||||
* @param alpha
|
* @param alpha Der neue Transparenzwert.
|
||||||
*/
|
*/
|
||||||
public Color( Color color, int alpha ) {
|
public Color( Color color, int alpha ) {
|
||||||
this(color.getRed(), color.getGreen(), color.getBlue(), 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.
|
* Erzeugt eine Farbe aus einem kodierten RGBA Integer-Wert.
|
||||||
|
* <p>
|
||||||
|
* 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
|
* @param rgba Eine RGBA-Farbe.
|
||||||
* @return
|
* @return Ein Farbobjekt.
|
||||||
*/
|
*/
|
||||||
public static Color getRGBColor( int rgba ) {
|
public static Color getRGBColor( int rgba ) {
|
||||||
return new Color(rgba, true);
|
return new Color(rgba, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erzeugt eine Farbe aus Werten im
|
||||||
|
* <a href="https://de.wikipedia.org/wiki/HSV-Farbraum">HSB-Farbraum</a>.
|
||||||
|
* <p>
|
||||||
|
* {code h} beschreibt den Farbwert (engl. <em>hue</em>), {@code s} die
|
||||||
|
* Sättigung (engl. <em>saturation</em>) und {@code b} die absolute
|
||||||
|
* Helligkeit (engl. <em>brightness</em>) 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 ) {
|
public static Color getHSBColor( double h, double s, double b ) {
|
||||||
return new Color(java.awt.Color.getHSBColor((float) h, (float) s, (float) b));
|
return new Color(java.awt.Color.getHSBColor((float) h, (float) s, (float) b));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erzeugt eine Farbe aus Werten im
|
||||||
|
* <a href="https://de.wikipedia.org/wiki/HSV-Farbraum">HSL-Farbraum</a>.
|
||||||
|
* <p>
|
||||||
|
* {code h} beschreibt den Farbwert (engl. <em>hue</em>), {@code s} die
|
||||||
|
* Sättigung (engl. <em>saturation</em>) und {@code l} die relative
|
||||||
|
* Helligkeit (engl. <em>lightness</em>) 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 ) {
|
public static Color getHSLColor( double h, double s, double l ) {
|
||||||
int rgb = Color.HSLtoRGB(new float[]{(float) h, (float) s, (float) l});
|
int rgb = Color.HSLtoRGB(new float[]{(float) h, (float) s, (float) l});
|
||||||
return Color.getRGBColor(rgb);
|
return Color.getRGBColor(rgb);
|
||||||
@@ -259,12 +292,16 @@ public class Color implements Paint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Erzeugt eine Farbe aus einem hexadezimalen Code. Der Hexcode kann sechs-
|
* Erzeugt eine Farbe aus einem hexadezimalen Code. Der Hexcode kann drei-,
|
||||||
* oder achtstellig sein (wenn ein Transparentwert vorhanden ist). Dem Code
|
* sechs- oder achtstellig sein (wenn ein Transparentwert vorhanden ist).
|
||||||
* kann ein {@code #} Zeichen vorangestellt sein.
|
* Dem Code kann ein {@code #} Zeichen vorangestellt sein, muss es aber
|
||||||
|
* nicht.
|
||||||
|
* <p>
|
||||||
|
* Bei einem dreistelligen Code wird jedes zeichen doppelt interpretiert.
|
||||||
|
* Das beduetet {@code #ABC} ist gleichbedeutend mit {@code #AABBCC}.
|
||||||
*
|
*
|
||||||
* @param hexcode
|
* @param hexcode Eine Farbe als Hexcode.
|
||||||
* @return
|
* @return Ein Farbobjekt.
|
||||||
*/
|
*/
|
||||||
public static Color parseHexcode( String hexcode ) {
|
public static Color parseHexcode( String hexcode ) {
|
||||||
if( hexcode.startsWith("#") ) {
|
if( hexcode.startsWith("#") ) {
|
||||||
@@ -301,7 +338,7 @@ public class Color implements Paint {
|
|||||||
if( color1 == null && color2 == null ) {
|
if( color1 == null && color2 == null ) {
|
||||||
throw new IllegalArgumentException("Color.interpolate() needs at least one color to be not 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();
|
return color1.copy();
|
||||||
}
|
}
|
||||||
if( t > 1.0 || color1 == null ) {
|
if( t > 1.0 || color1 == null ) {
|
||||||
@@ -351,6 +388,14 @@ public class Color implements Paint {
|
|||||||
return hsl;
|
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 ) {
|
public static int HSLtoRGB( float[] hsl ) {
|
||||||
return HSLtoRGB(hsl, 255);
|
return HSLtoRGB(hsl, 255);
|
||||||
}
|
}
|
||||||
@@ -359,9 +404,9 @@ public class Color implements Paint {
|
|||||||
* Konvertiert eine Farbe mit Komponenten im HSL-Farbraum in den
|
* Konvertiert eine Farbe mit Komponenten im HSL-Farbraum in den
|
||||||
* RGB-Farbraum.
|
* RGB-Farbraum.
|
||||||
* <p>
|
* <p>
|
||||||
* Die Farbkomponenten werden als Float-Array übergeben. Im Index 0 steht
|
* 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
|
* der H-Wert im Bereich 0 bis 360, Index 1 und 2 enthalten den S- und
|
||||||
* l-Wert im Bereich von 0 bis 1.
|
* L-Wert im Bereich von 0 bis 1.
|
||||||
*
|
*
|
||||||
* @param hsl Die Farbkomponenten im HSL-Farbraum.
|
* @param hsl Die Farbkomponenten im HSL-Farbraum.
|
||||||
* @param alpha Ein Transparenzwert im Bereich 0 bis 255.
|
* @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.
|
* Prüft, ob ein anderes Objekt zu diesem gleich ist.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
* @param obj Das zu vergleichende Objekt.
|
||||||
* @return {@code true}, wenn die Objekte gleich sind, sonst {@code false}.
|
* @return {@code true}, wenn die Objekte gleich sind, sonst {@code false}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1054,7 +1054,7 @@ public class Constants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ermittelt den Arkuskosinus der angegebenen Zahl.
|
* Ermittelt den Arcuskosinus der angegebenen Zahl.
|
||||||
*
|
*
|
||||||
* @param x Eine Zahl.
|
* @param x Eine Zahl.
|
||||||
* @return {@code acos(x)}.
|
* @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.
|
* @param x Eine Zahl.
|
||||||
* @return {@code atan(x)}.
|
* @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 ) {
|
public static final double asDouble( char value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( byte value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( short value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( long value ) {
|
||||||
return (double) 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 ) {
|
public static final double asDouble( double value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( float value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( int value ) {
|
||||||
return 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 ) {
|
public static final double asDouble( boolean value ) {
|
||||||
return value ? 1.0 : 0.0;
|
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 ) {
|
public static final double asDouble( String value ) {
|
||||||
try {
|
try {
|
||||||
return Double.parseDouble(value);
|
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 ) {
|
public static final boolean asBool( char value ) {
|
||||||
return value != 0;
|
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 ) {
|
public static final boolean asBool( byte value ) {
|
||||||
return value != 0;
|
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 ) {
|
public static final boolean asBool( short value ) {
|
||||||
return value != 0;
|
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 ) {
|
public static final boolean asBool( int value ) {
|
||||||
return value != 0;
|
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 ) {
|
public static final boolean asBool( long value ) {
|
||||||
return value != 0L;
|
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 ) {
|
public static final boolean asBool( double value ) {
|
||||||
return value != 0.0;
|
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 ) {
|
public static final boolean asBool( float value ) {
|
||||||
return value != 0.0f;
|
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 ) {
|
public static final boolean asBool( boolean value ) {
|
||||||
return 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 ) {
|
public static final boolean asBool( String value ) {
|
||||||
return Boolean.parseBoolean(value);
|
return Boolean.parseBoolean(value);
|
||||||
}
|
}
|
||||||
@@ -1813,7 +1923,7 @@ public class Constants {
|
|||||||
return Integer.valueOf(binary, 16);
|
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.
|
* Constant for the ENTER virtual key.
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ import java.awt.image.BufferedImage;
|
|||||||
* Die {@code Zeichenleinwand} besteht aus einer Reihe von Ebenen, die
|
* Die {@code Zeichenleinwand} besteht aus einer Reihe von Ebenen, die
|
||||||
* übereinandergelegt und von "unten" nach "oben" gezeichnet werden. Die Inhalte
|
* übereinandergelegt und von "unten" nach "oben" gezeichnet werden. Die Inhalte
|
||||||
* der oberen Ebenen können also Inhalte der darunterliegenden verdecken.
|
* der oberen Ebenen können also Inhalte der darunterliegenden verdecken.
|
||||||
*
|
* <p>
|
||||||
* Ebenen sind ein zentraler Bestandteil bei der Implementierung einer {@link Zeichenmaschine}.
|
* Ebenen sind ein zentraler Bestandteil bei der Implementierung einer
|
||||||
* Es werden
|
* {@link Zeichenmaschine}. Sie erben von {@code Constants}, da neue Ebenentypen
|
||||||
* Sie erben von {@code Constants}, damit sie beim
|
* von Nutzern implementiert werden können.
|
||||||
*/
|
*/
|
||||||
public abstract class Layer extends Constants implements Drawable, Updatable {
|
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;
|
protected boolean active = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt eine neue Ebene mit den Standardmaßen.
|
||||||
|
*/
|
||||||
public Layer() {
|
public Layer() {
|
||||||
this(DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
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 ) {
|
public Layer( int width, int height ) {
|
||||||
createCanvas(width, height);
|
createCanvas(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Die Breite der Ebene.
|
||||||
|
*/
|
||||||
public int getWidth() {
|
public int getWidth() {
|
||||||
return buffer.getWidth();
|
return buffer.getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Die Höhe der Ebene.
|
||||||
|
*/
|
||||||
public int getHeight() {
|
public int getHeight() {
|
||||||
return buffer.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 width Die neue Breite.
|
||||||
* @param height Die neue Höhe.
|
* @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.
|
* 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.
|
* @param height Höhe des neuen Puffers.
|
||||||
*/
|
*/
|
||||||
private void createCanvas( int width, int height ) {
|
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
|
* Erstellt einen neuen Puffer für die Ebene mit der angegebenen Größe und
|
||||||
* kopiert den Inhalt des alten Puffers in den Neuen.
|
* 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.
|
* @param height Höhe des neuen Puffers.
|
||||||
*/
|
*/
|
||||||
private void recreateCanvas( int width, int height ) {
|
private void recreateCanvas( int width, int height ) {
|
||||||
@@ -155,14 +170,26 @@ public abstract class Layer extends Constants implements Drawable, Updatable {
|
|||||||
return visible;
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versteckt die Ebene.
|
||||||
|
*/
|
||||||
public void hide() {
|
public void hide() {
|
||||||
visible = false;
|
visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void view() {
|
/**
|
||||||
|
* Zeigt die Ebene an, falls sie versteckt war.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public void show() {
|
||||||
visible = true;
|
visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versteckt oder zeigt die Ebene, je nachdem, welchen Zustand sie derzeit
|
||||||
|
* hat.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public void toggle() {
|
public void toggle() {
|
||||||
visible = !visible;
|
visible = !visible;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,17 +11,71 @@ public final class Options {
|
|||||||
private Options() {
|
private Options() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Linienstile für Konturlinien.
|
||||||
|
*/
|
||||||
public enum StrokeType {
|
public enum StrokeType {
|
||||||
SOLID, DASHED, DOTTED
|
/**
|
||||||
|
* Durchgezogene Linien.
|
||||||
|
*/
|
||||||
|
SOLID,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getrichelte Linien.
|
||||||
|
*/
|
||||||
|
DASHED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gepunktete Linien.
|
||||||
|
*/
|
||||||
|
DOTTED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stile für Pfeilspitzen.
|
||||||
|
*/
|
||||||
public enum ArrowHead {
|
public enum ArrowHead {
|
||||||
LINES, FILLED
|
/**
|
||||||
|
* Einfache Pfeilspitze aus zwei Linien.
|
||||||
|
*/
|
||||||
|
LINES,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gefülltes Dreieck.
|
||||||
|
*/
|
||||||
|
FILLED
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arten von Bögen.
|
||||||
|
* <p>
|
||||||
|
* Die Werte legen fest, wie Bögen geschlossen werden sollen, wenn sie
|
||||||
|
* beispielsweise gefüllt werden.
|
||||||
|
* <p>
|
||||||
|
* Wrapper für die AWT-Konstanten in {@link Arc2D}.
|
||||||
|
*/
|
||||||
public enum PathType {
|
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;
|
public final int awt_type;
|
||||||
|
|
||||||
PathType( int type ) {
|
PathType( int type ) {
|
||||||
@@ -33,25 +87,100 @@ public final class Options {
|
|||||||
* Zustände in denen sich die Zeichenmaschine befinden kann.
|
* Zustände in denen sich die Zeichenmaschine befinden kann.
|
||||||
*/
|
*/
|
||||||
public enum AppState {
|
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,
|
INITIALIZING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Initialisierung der Zeichenmaschine ist beendet, aber der
|
||||||
|
* {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread}
|
||||||
|
* wurde noch nicht gestartet.
|
||||||
|
*/
|
||||||
INITIALIZED,
|
INITIALIZED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeichenmaschine wurde gestartet und der
|
||||||
|
* {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread}
|
||||||
|
* arbeitet.
|
||||||
|
*/
|
||||||
RUNNING,
|
RUNNING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread}
|
||||||
|
* wurde pausiert.
|
||||||
|
*/
|
||||||
PAUSED,
|
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,
|
STOPPED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread}
|
||||||
|
* ist beendet.
|
||||||
|
*/
|
||||||
TERMINATED,
|
TERMINATED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeichenmaschine ist dabei, vollständig herunterzufahren und alle
|
||||||
|
* Ressourcen freizugeben.
|
||||||
|
*/
|
||||||
QUITING,
|
QUITING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der {@link schule.ngb.zm.Zeichenmaschine.Zeichenthread Zeichenthread}
|
||||||
|
* wartet gerade auf den nächsten Frame.
|
||||||
|
*/
|
||||||
IDLE,
|
IDLE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeichenmaschine führt gerade
|
||||||
|
* {@link Zeichenmaschine#update(double)} aus.
|
||||||
|
*/
|
||||||
UPDATING,
|
UPDATING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeichenmaschine führt gerade {@link Zeichenmaschine#draw()} aus.
|
||||||
|
*/
|
||||||
DRAWING,
|
DRAWING,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Ausführung der Zeichenmaschine wurde mit
|
||||||
|
* {@link Zeichenmaschine#delay(int)} verzögert und wartet auf
|
||||||
|
* Fortsetzung.
|
||||||
|
*/
|
||||||
DELAYED,
|
DELAYED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Zeichenmaschine sendet gereade gesammelte Events und führt Tasks
|
||||||
|
* aus.
|
||||||
|
*/
|
||||||
DISPATCHING
|
DISPATCHING
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Richtungen für die Ausrichtung von Formen. Richtungen sind durch
|
* Richtungen für die Ausrichtung von Formen. Richtungen sind durch
|
||||||
* Einheitsvektoren bzw. deren Kombination repräsentiert, wodurch mit ihnen
|
* Einheitsvektoren bzw. deren Kombination im Koordinatensystem der
|
||||||
* gerechnet werden kann. Jede Richtung ist zusätzlich als Himmelsrichtung
|
* Zeichenfläche repräsentiert, wodurch mit ihnen gerechnet werden kann. Die
|
||||||
* definiert.
|
* Richtung {@link #DOWN} ist beispielsweise gleich {@code (1, 0)}.
|
||||||
|
* <p>
|
||||||
|
* 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.
|
||||||
|
* <p>
|
||||||
|
* 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 {
|
public enum Direction {
|
||||||
CENTER(0, 0),
|
CENTER(0, 0),
|
||||||
@@ -89,30 +218,116 @@ public final class Options {
|
|||||||
this.y = original.y;
|
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.
|
||||||
|
* <p>
|
||||||
|
* 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}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* NORTH.in(NORTHWEST) // true
|
||||||
|
* NORTH.in(SOUTHWEST) // false
|
||||||
|
* UP.in(NORTHWEST) // true
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dir Eine andere Richtung.
|
||||||
|
* @return {@code true}, wenn diese Richtungen Teil der anderen ist,
|
||||||
|
* {@code false} sonst.
|
||||||
|
*/
|
||||||
public boolean in( Direction dir ) {
|
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);
|
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.
|
||||||
|
* <p>
|
||||||
|
* 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}.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* NORTHWEST.contains(NORTH) // true
|
||||||
|
* SOUTHWEST.in(NORTH) // false
|
||||||
|
* NORTHWEST.in(UP) // true
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @param dir Eine andere Richtung.
|
||||||
|
* @return {@code true}, wenn diese Richtungen Teil der anderen ist,
|
||||||
|
* {@code false} sonst.
|
||||||
|
*/
|
||||||
public boolean contains( Direction dir ) {
|
public boolean contains( Direction dir ) {
|
||||||
return dir.in(this);
|
return dir.in(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Diese Richtung als Vektor-Objekt.
|
||||||
|
*/
|
||||||
public Vector asVector() {
|
public Vector asVector() {
|
||||||
return new Vector(x, y);
|
return new Vector(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gibt die entgegengesetzte Richtung zu dieser zurück.
|
* Liefert die entgegengesetzte Richtung zu dieser.
|
||||||
|
* <p>
|
||||||
|
* 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() {
|
public Direction inverse() {
|
||||||
for( Direction dir : Direction.values() ) {
|
switch( this ) {
|
||||||
if( dir.x == -this.x && dir.y == -this.y ) {
|
case UP:
|
||||||
return dir;
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import java.awt.Stroke;
|
|||||||
* {@link Strokeable#setStrokeColor(Color, int)} Methode hat, dann sollte auch
|
* {@link Strokeable#setStrokeColor(Color, int)} Methode hat, dann sollte auch
|
||||||
* eine {@link schule.ngb.zm.layers.TurtleLayer.Turtle} dieselbe Methode
|
* eine {@link schule.ngb.zm.layers.TurtleLayer.Turtle} dieselbe Methode
|
||||||
* anbieten. Im Einzelfall kann es sinnvoll sein, weitere Methoden für
|
* 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.
|
* Möglichkeit zugunsten einer einheitlichen API abgesehen werden.
|
||||||
* <p>
|
* <p>
|
||||||
* Das Äquivalent für Füllungen stellt {@link Fillable} dar.
|
* Das Äquivalent für Füllungen stellt {@link Fillable} dar.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public interface Updatable {
|
|||||||
* @return {@code true}, wenn das Objekt aktiv ist, {@code false}
|
* @return {@code true}, wenn das Objekt aktiv ist, {@code false}
|
||||||
* andernfalls.
|
* andernfalls.
|
||||||
*/
|
*/
|
||||||
public boolean isActive();
|
boolean isActive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Änderung des Zustandes des Objekts abhängig vom Zeitintervall
|
* Ä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).
|
* @param delta Zeitintervall seit dem letzten Aufruf (in Sekunden).
|
||||||
*/
|
*/
|
||||||
public void update( double delta );
|
void update( double delta );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,8 +422,8 @@ public class Vector extends Point2D.Double {
|
|||||||
* dem quadrierten Abstand durchführen, wenn auch die gewünschte Entfernung
|
* dem quadrierten Abstand durchführen, wenn auch die gewünschte Entfernung
|
||||||
* quadriert wird.
|
* quadriert wird.
|
||||||
*
|
*
|
||||||
* @param vector
|
* @param vector Ein anderer Vektor.
|
||||||
* @return
|
* @return Das Quadrat der Entfernung zum anderen Vektor.
|
||||||
*/
|
*/
|
||||||
public double distanceSq( Vector vector ) {
|
public double distanceSq( Vector vector ) {
|
||||||
return super.distanceSq(vector);
|
return super.distanceSq(vector);
|
||||||
|
|||||||
@@ -9,9 +9,7 @@ import java.awt.*;
|
|||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.KeyListener;
|
import java.awt.event.KeyListener;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -25,6 +23,12 @@ import java.util.ArrayList;
|
|||||||
*/
|
*/
|
||||||
public class Zeichenfenster extends JFrame {
|
public class Zeichenfenster extends JFrame {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzt das Look and Feel auf den Standard des Systems.
|
||||||
|
* <p>
|
||||||
|
* Sollte einmalig vor erstellen des erstyen Programmfensters aufgerufen
|
||||||
|
* werden.
|
||||||
|
*/
|
||||||
public static final void setLookAndFeel() {
|
public static final void setLookAndFeel() {
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
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() {
|
public static final GraphicsDevice getGraphicsDevice() {
|
||||||
// Wir suchen den Bildschirm, der derzeit den Mauszeiger enthält, um
|
// Wir suchen den Bildschirm, der derzeit den Mauszeiger enthält, um
|
||||||
// das Zeichenfenster dort zu zentrieren.
|
// 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
|
* Das Anzeigegerät, auf dem die Zeichenmaschine gestartet wurde (muss nicht
|
||||||
* Aktuellen sein, wenn das Fenster verschoben wurde).
|
* 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
|
* 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 ) {
|
public Zeichenfenster( int width, int height, String title ) {
|
||||||
this(new Zeichenleinwand(width, height), title, getGraphicsDevice());
|
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 ) {
|
public Zeichenfenster( int width, int height, String title, GraphicsDevice displayDevice ) {
|
||||||
this(new Zeichenleinwand(width, height), title, 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 ) {
|
public Zeichenfenster( Zeichenleinwand canvas, String title ) {
|
||||||
this(canvas, title, getGraphicsDevice());
|
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 ) {
|
public Zeichenfenster( Zeichenleinwand canvas, String title, GraphicsDevice displayDevice ) {
|
||||||
super(Validator.requireNotNull(displayDevice).getDefaultConfiguration());
|
super(Validator.requireNotNull(displayDevice).getDefaultConfiguration());
|
||||||
this.displayDevice = displayDevice;
|
this.displayDevice = displayDevice;
|
||||||
@@ -124,14 +175,19 @@ public class Zeichenfenster extends JFrame {
|
|||||||
try {
|
try {
|
||||||
if( Zeichenmaschine.MACOS ) {
|
if( Zeichenmaschine.MACOS ) {
|
||||||
URL iconUrl = Zeichenmaschine.class.getResource("icon_512.png");
|
URL iconUrl = Zeichenmaschine.class.getResource("icon_512.png");
|
||||||
Image icon = ImageIO.read(iconUrl);
|
if( iconUrl != null ) {
|
||||||
// Dock Icon in macOS setzen
|
Image icon = ImageIO.read(iconUrl);
|
||||||
Taskbar taskbar = Taskbar.getTaskbar();
|
// Dock Icon in macOS setzen
|
||||||
taskbar.setIconImage(icon);
|
Taskbar taskbar = Taskbar.getTaskbar();
|
||||||
|
taskbar.setIconImage(icon);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ArrayList<Image> icons = new ArrayList<>(4);
|
ArrayList<Image> icons = new ArrayList<>(4);
|
||||||
for( int size: new int[]{32, 64, 128, 512} ) {
|
for( int size : new int[]{32, 64, 128, 512} ) {
|
||||||
icons.add(ImageIO.read(new File("icon_" + size + ".png")));
|
URL icnUrl = Zeichenmaschine.class.getResource("icon_" + size + ".png");
|
||||||
|
if( icnUrl != null ) {
|
||||||
|
icons.add(ImageIO.read(icnUrl));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setIconImages(icons);
|
this.setIconImages(icons);
|
||||||
@@ -150,19 +206,45 @@ public class Zeichenfenster extends JFrame {
|
|||||||
// this.centerFrame();
|
// this.centerFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert das Anzeigegerät, auf dem dieses Fenster erstellt wurde.
|
||||||
|
* <p>
|
||||||
|
* 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() {
|
public GraphicsDevice getDisplayDevice() {
|
||||||
return displayDevice;
|
return displayDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert die Abmessungen des Anzeigegeräts, auf dem das Fenster gestartet
|
||||||
|
* wurde.
|
||||||
|
*
|
||||||
|
* @return Die Abmessungen des Anzeigegeräts.
|
||||||
|
*/
|
||||||
public Rectangle getScreenBounds() {
|
public Rectangle getScreenBounds() {
|
||||||
// return GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
|
// return GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds();
|
||||||
return displayDevice.getDefaultConfiguration().getBounds();
|
return displayDevice.getDefaultConfiguration().getBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert die Zeichenleinwand dieses Fensters.
|
||||||
|
*
|
||||||
|
* @return Die Zeichenleinwand.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
public Zeichenleinwand getCanvas() {
|
public Zeichenleinwand getCanvas() {
|
||||||
return canvas;
|
return canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert die Abmessungen der Zeichenleinwand zurück.
|
||||||
|
*
|
||||||
|
* @return Die Abmessungen der Zeichenleinwand.
|
||||||
|
*/
|
||||||
public Rectangle getCanvasBounds() {
|
public Rectangle getCanvasBounds() {
|
||||||
return canvas.getBounds();
|
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 ) {
|
public void setCanvasSize( int newWidth, int newHeight ) {
|
||||||
// TODO: (ngb) Put constrains on max/min frame/canvas size
|
// TODO: (ngb) Put constrains on max/min frame/canvas size
|
||||||
if( fullscreen ) {
|
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() {
|
public boolean isFullscreen() {
|
||||||
Window win = displayDevice.getFullScreenWindow();
|
Window win = displayDevice.getFullScreenWindow();
|
||||||
return fullscreen && win.equals(this);
|
return fullscreen && win.equals(this);
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package schule.ngb.zm;
|
package schule.ngb.zm;
|
||||||
|
|
||||||
import schule.ngb.zm.layers.ColorLayer;
|
|
||||||
import schule.ngb.zm.util.Log;
|
import schule.ngb.zm.util.Log;
|
||||||
|
|
||||||
import java.awt.Canvas;
|
import java.awt.Canvas;
|
||||||
@@ -8,7 +7,10 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.image.BufferStrategy;
|
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
|
* Eine Leinwand ist die Hauptkomponente einer Zeichenmaschine. Sie besteht aus
|
||||||
@@ -22,13 +24,13 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public class Zeichenleinwand extends Canvas {
|
public class Zeichenleinwand extends Canvas {
|
||||||
|
|
||||||
|
// Lokales Lock für Rendervorgänge.
|
||||||
private final Object[] renderLock = new Object[0];
|
private final Object[] renderLock = new Object[0];
|
||||||
|
|
||||||
/**
|
// Liste der hinzugefügten Ebenen.
|
||||||
* Liste der hinzugefügten Ebenen.
|
|
||||||
*/
|
|
||||||
private final List<Layer> layers;
|
private final List<Layer> layers;
|
||||||
|
|
||||||
|
// Status der Zeichenleinwand.
|
||||||
private boolean rendering = false, suspended = false;
|
private boolean rendering = false, suspended = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,6 +82,10 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setzt das Zeichnen der Leinwand fort, falls es zuvor mit
|
||||||
|
* {@link #suspendRendering()} ausgesetzt wurde.
|
||||||
|
*/
|
||||||
public void resumeRendering() {
|
public void resumeRendering() {
|
||||||
suspended = false;
|
suspended = false;
|
||||||
}
|
}
|
||||||
@@ -201,6 +207,7 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
* @param <L> Typ der Ebenen, die abgefragt werden.
|
* @param <L> Typ der Ebenen, die abgefragt werden.
|
||||||
* @return Eine Liste mit den vorhandenen Ebenen des abgefragten Typs.
|
* @return Eine Liste mit den vorhandenen Ebenen des abgefragten Typs.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
public <L extends Layer> List<L> getLayers( Class<L> type ) {
|
public <L extends Layer> List<L> getLayers( Class<L> type ) {
|
||||||
ArrayList<L> result = new ArrayList<>(layers.size());
|
ArrayList<L> result = new ArrayList<>(layers.size());
|
||||||
synchronized( layers ) {
|
synchronized( layers ) {
|
||||||
@@ -213,10 +220,24 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt die angegebene Ebene von dieser Zeichenleinwand.
|
||||||
|
*
|
||||||
|
* @param pLayer Die Ebene, die entfernt werden soll.
|
||||||
|
* @return {@code true}, wenn die Liste vorhanden war und entfernt wurde,
|
||||||
|
* {@code false} sonst.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
public boolean removeLayer( Layer pLayer ) {
|
public boolean removeLayer( Layer pLayer ) {
|
||||||
return layers.remove(pLayer);
|
return layers.remove(pLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt alle angegebenen Ebenen von dieser Zeichenleinwand.
|
||||||
|
*
|
||||||
|
* @param removeLayers Die Ebenen, die entfernt werden sollen.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
public void removeLayers( Layer... removeLayers ) {
|
public void removeLayers( Layer... removeLayers ) {
|
||||||
synchronized( layers ) {
|
synchronized( layers ) {
|
||||||
for( Layer layer : removeLayers ) {
|
for( Layer layer : removeLayers ) {
|
||||||
@@ -225,10 +246,21 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entfernt alle vorhandenen Ebenen von dieser Zeichenleinwand.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unused" )
|
||||||
public void clearLayers() {
|
public void clearLayers() {
|
||||||
layers.clear();
|
layers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aktualisiert alle {@link Layer Ebenen}, die dieser Zeichenleinwand
|
||||||
|
* hinzugefügt wurden.
|
||||||
|
*
|
||||||
|
* @param delta Die Zeit seit dem letzten Aufruf in Sekunden.
|
||||||
|
* @see Layer#update(double)
|
||||||
|
*/
|
||||||
public void updateLayers( double delta ) {
|
public void updateLayers( double delta ) {
|
||||||
synchronized( layers ) {
|
synchronized( layers ) {
|
||||||
for( Layer layer : List.copyOf(layers) ) {
|
for( Layer layer : List.copyOf(layers) ) {
|
||||||
@@ -261,9 +293,9 @@ public class Zeichenleinwand extends Canvas {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zeichnet den Inhalt aller {@link Layer Ebenen} in den Grafik-Kontext.
|
* Zeichnet den Inhalt aller {@link Layer Ebenen} in den Grafikkontext.
|
||||||
*
|
*
|
||||||
* @param graphics
|
* @param graphics Der Grafikkontext.
|
||||||
*/
|
*/
|
||||||
public void draw( Graphics graphics ) {
|
public void draw( Graphics graphics ) {
|
||||||
Graphics2D g2d = (Graphics2D) graphics.create();
|
Graphics2D g2d = (Graphics2D) graphics.create();
|
||||||
|
|||||||
@@ -679,9 +679,9 @@ public class Zeichenmaschine extends Constants {
|
|||||||
* Gibt die erste (unterste) {@link Layer Ebene} der angegebenen Klasse
|
* Gibt die erste (unterste) {@link Layer Ebene} der angegebenen Klasse
|
||||||
* zurück.
|
* zurück.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre><code>
|
||||||
* DrawingLayer draw = getLayer(DrawingLayer.class);
|
* DrawingLayer draw = getLayer(DrawingLayer.class);
|
||||||
* </pre>
|
* </code></pre>
|
||||||
*
|
*
|
||||||
* @param layerClass
|
* @param layerClass
|
||||||
* @param <LT>
|
* @param <LT>
|
||||||
@@ -947,9 +947,9 @@ public class Zeichenmaschine extends Constants {
|
|||||||
* <p>
|
* <p>
|
||||||
* Die Konstanten der Klasse {@link Cursor} definieren 13 Standardzeiger,
|
* Die Konstanten der Klasse {@link Cursor} definieren 13 Standardzeiger,
|
||||||
* die durch angabe der Nummer geladen werden können.
|
* die durch angabe der Nummer geladen werden können.
|
||||||
* <pre>
|
* <pre><code>
|
||||||
* setCursor(Cursor.HAND_CURSOR);
|
* setCursor(Cursor.HAND_CURSOR);
|
||||||
* </pre>
|
* </code></pre>
|
||||||
*
|
*
|
||||||
* @param pPredefinedCursor Eine der Cursor-Konstanten.
|
* @param pPredefinedCursor Eine der Cursor-Konstanten.
|
||||||
* @see Cursor
|
* @see Cursor
|
||||||
@@ -1022,9 +1022,9 @@ public class Zeichenmaschine extends Constants {
|
|||||||
* {@code delta} wird in Sekunden angegeben. Um eine Form zum Beispiel um
|
* {@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
|
* {@code 50} Pixel pro Sekunde in {@code x}-Richtung zu bewegen, kann so
|
||||||
* vorgegangen werden:
|
* vorgegangen werden:
|
||||||
* <pre>
|
* <pre><code>
|
||||||
* shape.move(50*delta, 0.0);
|
* shape.move(50*delta, 0.0);
|
||||||
* </pre>
|
* </code></pre>
|
||||||
*
|
*
|
||||||
* @param delta
|
* @param delta
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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 source
|
||||||
* @param charset
|
* @param charset
|
||||||
@@ -161,7 +161,7 @@ public final class FileLoader {
|
|||||||
).toArray(double[][]::new);
|
).toArray(double[][]::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileLoader() {
|
private FileLoader() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Log LOG = Log.getLogger(FileLoader.class);
|
private static final Log LOG = Log.getLogger(FileLoader.class);
|
||||||
|
|||||||
Reference in New Issue
Block a user