5 Commits

Author SHA1 Message Date
b76d533739 Erste Seiten mit mkdocs 2022-11-29 10:55:54 +01:00
807a13b725 buildfile cleanup 2022-11-29 10:55:22 +01:00
d4c5dbbb53 Gradle 7.4 -> 7.5 2022-11-29 10:55:10 +01:00
080db1f431 Einige Bugfixes und Verbesserungen und ganz viel Doku 2022-11-29 10:12:14 +01:00
47827683e8 Farbnamen werden nun in Colo-Objekte geparsed
`Color.parseString(String)` liest nun eine Datei mit Farbnamen und Hexcode Kombinationen ein. Wird der String in der Liste der Farbnamen gefunden, wird aus dem entsprechenden Hexcode ein `Color`-Objekt erzeugt.
2022-11-29 10:11:43 +01:00
32 changed files with 1420 additions and 116 deletions

View File

@@ -3,16 +3,6 @@ plugins {
id 'java-library' id 'java-library'
} }
/*properties {
zmVersion {
major = 0;
minor = 0;
rev = 32;
}
}
version '{$zmVersion.major}.{$zmVersion.minor}.{$zmVersion.rev}-SNAPSHOT'
*/
group 'schule.ngb' group 'schule.ngb'
version '0.0.32-SNAPSHOT' version '0.0.32-SNAPSHOT'

BIN
docs/assets/icon_128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/assets/icon_32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
docs/assets/icon_512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

BIN
docs/assets/icon_64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

12
docs/assets/zmstyles.css Normal file
View File

@@ -0,0 +1,12 @@
h1.title {
text-align: center;
color: #363636;
margin-bottom: .25rem;
}
h2.subtitle {
text-align: center;
font-size: 1rem;
color: #4a4a4a;
margin-top: -.25rem;
margin-bottom: -1.25rem;
}

View File

@@ -0,0 +1,7 @@
{% extends "base.html" %}
{% block tabs %}
{{ super() }}
{% endblock %}
{% block content %}{% endblock %}
{% block footer %}{% endblock %}

43
docs/index.md Normal file
View File

@@ -0,0 +1,43 @@
<figure markdown>
![Zeichenmaschine.xyz](assets/icon_512.png){ width=128 }
</figure>
<h1 class="title">Zeichenmaschine.xyz</h1>
<h2 class="subtitle">Eine kleine Java-Bibliothek für grafische Programmierung im
Informatikunterricht.</h2>
## Projektidee
Die **Zeichenmaschine** ist eine für den Informatikunterricht entwickelte Bibliothek,
die unter anderem an [Processing](https://processing.org/) angelehnt ist. Die
Bibliothek soll einige der üblichen Anfängerschwierigkeiten mit Java vereinfachen
und für Schülerinnen und Schüler im Unterricht nutzbar machen.
!!! warning
Das Projekt befindet sich noch in der Entwicklungsphase und auch wenn die
aktuelle Version schon funktionsfähig ist und einen Großteil der angestrebten
Funktionen enthält, ist noch keine stabile Version 1.0 erreicht. Vor allem
am Umfang und konsistenten Design der APIs gilt es noch zu arbeiten und es
können sich Änderungen ergeben.
Feedback und Vorschläge zu diesem Prozess (oder auch eine Beteiligung an der
Entwicklung) können sehr gerne über [Github](https://github.com/jneug) oder
[Mastodon](https://bildung.social/@ngb) an mich kommuniziert werden.
(Gleiches gilt für diese Webseite zum Projekt.)
## Dokumentation
* [Schnellstart](quickstart.md)
* [Installation](install.md)
* {{ javadoc_link() }}
## Über die Zeichenmaschine
!!! info
In der Zeichenmaschine werden bewusst nur englischsprachige Bezeichner für
Klassen, Methoden und Variablen verwendet. Ausnahme sind einzelne Klassen,
die im Zusammnehang mit dem Namen der Bibliothek stehen, wie die
Hauptklasse `Zeichenmaschine`.

44
docs/install.md Normal file
View File

@@ -0,0 +1,44 @@
# Installation
Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr
nötig, als
die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest)
herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Beschreibungen
für
verschiedene Entwicklungsumgebungen sind hier aufgelistet.
## Integration in Entwicklungsumgebungen
### BlueJ
[BlueJ](https://bluej.org) sucht an drei Orten nach Bibliotheken, die für ein
Projekt in den Classpath aufgenommen werden:
- Für ein einzelnes Projekt im Projektordner im Unterordner `+libs`.
- Im Reiter "Bibliotheken" der BlueJ-Einstellungen.
Hier können Programmbibliotheken hinzugefügt werden, die dann allen Projekten
zur Verfügung stehen.
- Für alle Projekte und alle Nutzer dieser BlueJ-Version im
Unterordner `userlib` des Programmordners.
Auf Windows-Systemen ist dieser im Order `lib` des Installationsordners von BlueJ zu finden.
Auf macos-Systemen muss via Rechtsklick auf die Programmdatei `BlueJ.app` über den Menüpunkt "Paketinhalt zeigen" in den Ordner `Contents/Resources/Java/` navigiert werden.
### VSCode / VSCodium
> Coming soon
### IntelliJ
> Coming soon
### Eclipse
> Coming soon
### NetBeans
> Coming soon

63
docs/macros.py Normal file
View File

@@ -0,0 +1,63 @@
import re
from typing import List
def define_env(env):
@env.macro
def javadoc(clazz: str = None, target: str = None) -> str:
if not "javadoc_url" in env.variables:
return clazz
if not clazz:
return f"{env.variables['javadoc_url'].rstrip('/')}/index.html"
else:
if "javadoc_default_package" in env.variables and not clazz.startswith(env.variables['javadoc_default_package']):
clazz = f"{env.variables['javadoc_default_package'].rstrip('.')}.{clazz}"
javadoc_url = env.variables["javadoc_url"].rstrip("/")
path = clazz.replace(".", "/") + ".html"
if target:
path = f"{path}#{target}"
return f"{javadoc_url}/{path}"
@env.macro
def javadoc_link(
clazz: str = None, target: str = None, strip_package: bool = True, strip_clazz: bool = False, title: str = None
) -> str:
name = clazz or "Javadoc"
if strip_package:
if clazz and clazz.rfind(".") > -1:
name = clazz[clazz.rfind(".") + 1 :]
if target:
# _target = re.sub(r"([^(][^,]*?\.)*?([^)]+)", lambda m: m.group(2), target)
_target = target
if strip_clazz:
name = _target
else:
name = f"{name}.{_target}"
if title:
name = title
return f"[{name}]({javadoc(clazz, target)})"
@env.macro
def javadoc_signature(
clazz: str = None,
member: str = None,
package: str = None,
params: List[str] = list(),
) -> str:
sig = clazz or ""
if clazz and package:
sig = f"{package}.{sig}"
if member:
sig = f"{sig}#{member}"
pparams = ",".join(params)
sig = f"{sig}({pparams})"
return sig
# schule/ngb/zm/Zeichenmaschine.html#setCursor(java.awt.Image,int,int)
# schule/ngb/zm/Zeichenmaschine.html#getLayer(java.lang.Class)
# schule/ngb/zm/DrawableLayer.html#add(schule.ngb.zm.Drawable...)

View File

@@ -0,0 +1,130 @@
# Schnellstart mit der Zeichenmaschine
Um ein einfaches Projekt mit der **Zeichenmaschine** aufzusetzen ist nicht mehr
nötig, als die [JAR-Datei der aktuellen Version](https://github.com/jneug/zeichenmaschine/release/latest)
herunterzuladen und dem *Classpath* des Projekts hinzuzufügen. Eine Beschreibung
für verschiedene Entwicklungsumgebungen findet sich im Abschnitt [Installation](install.md).
## Die Basisklasse
Um eine Zeichenmaschine zu erstellen, muss eine Unterklasse von {{ javadoc_link("schule.ngb.zm.Zeichenmaschine") }}
erstellt werden.
```java
public class Shapes extends Zeichenmaschine {
}
```
Die gezeigte Klasse ist schon eine lauffähige Zeichenmaschine und kann gestartet
werden.
!!! note
Bei einigen Entwicklungsumgebungen muss noch eine `main`-Methode erstellt
werden, um die Zeichenmaschine zu starten:
```java
public static void main(String[] args) {
new Shapes();
}
```
Es öffnet sich ein Zeichenfenster in einer vordefinierten Größe. Um die Größe und
den Titel des Fensters zu ändern, legen wir einen Konstruktor an.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
}
```
Starten wir das Projekt nun, wird das Zeichenfenster in der Größe 800x800 mit
dem Titel "Shapes" angezeigt.
<figure markdown>
![Shapes 2](assets/quickstart/shapes_2.png){ width=400 }
</figure>
### Formen zeichnen
Eine Zeichenmaschine hat verschiedene Möglichkeiten, Inhalte in das Zeichenfenster
zu zeichnen. Um einfach nur ein statisches Bild zu erzeugen, überschreiben wir die
{{ javadoc_link("schule.ngb.zm.Zeichenmaschine", "draw()") }} Methode.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
@Override
public void draw() {
background.setColor(43, 128, 243);
drawing.setFillColor(255, 223, 34);
drawing.noStroke();
drawing.circle(400, 400, 100);
}
}
```
Nun haben wir einen gelben Kreis (ohne Konturlinie) auf einem blauen Hintergrund
gezeichnet.
<figure markdown>
![Shapes 3](assets/quickstart/shapes_3.png){ width=400 }
</figure>
### Vorbereitung der Zeichenfläche
Im Beispiel oben setzen wir die Hintergrundfarbe auf Blau, die Füllfarbe auf Gelb
und deaktivieren die Konturlinie. Wenn diese Einstellungen für alle Zeichenobjekte
gleich sind, können wir sie statt in `draw()` auch in die `setup()` Methode schreiben.
Diese bereitet die Zeichenfläche vor dem ersten Zeichnen vor.
```java
public class Shapes extends Zeichenmaschine {
public Shapes() {
super(800, 800, "Shapes");
}
@Override
public void setup() {
background.setColor(43, 128, 243);
drawing.setFillColor(255, 223, 34);
drawing.noStroke();
}
@Override
public void draw() {
for( int i = 0; i < 10; i++ ) {
drawing.circle(
random(0, canvasWidth),
random(0, canvasHeight),
random(50, 200)
);
}
}
}
```
Im Beispiel setzen wir nun die Grundeinstellungen in der `setup()` Methode. In
`draw()` werden zehn gelbe Kreise an Zufallskoordinaten gezeichnet.
<figure markdown>
![Shapes 4](assets/quickstart/shapes_4.1.png){ width=400 }
</figure>
!!! tip ""
Mit {{ javadoc_link("Constants", "canvasWidth", title="canvasWidth") }} und {{ javadoc_link("Constants", "canvasHeight", strip_clazz=True) }} kannst du in der Zeichenmaschine auf
die aktuelle Größe der Zeichenfläche zugreifen. {{ javadoc_link("Constants", "random(int,int)") }}
erzeugt eine Zufallszahl innerhalb der angegebenen Grenzen.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

76
mkdocs.yml Normal file
View File

@@ -0,0 +1,76 @@
site_name: Zeichenmaschine.xyz
site_description: Eine kleine Java-Bibliothek für grafische Programmierung im Informatikunterricht.
site_author: J. Neugebauer
repo_url: https://github.com/jneug/zeichenmaschine
repo_name: jneug/zeichenmaschine
site_dir: build/docs/site
theme:
name: material
custom_dir: docs/home_override/
language: de
logo: assets/icon_64.png
favicon: assets/icon_32.png
features:
- content.code.annotate
- navigation.top
- navigation.tracking
- search.suggest
font: false
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: blue
accent: deep orange
toggle:
icon: material/weather-sunny
name: Dunkles Design aktivieren
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: blue
accent: deep orange
toggle:
icon: material/weather-night
name: Helles Design aktivieren
extra_css:
- assets/zmstyles.css
nav:
- Einführung: index.md
- Schnellstart: quickstart.md
- Installation: install.md
markdown_extensions:
- admonition
- attr_list
- def_list
- footnotes
- md_in_html
- toc:
permalink: true
- pymdownx.magiclink
- pymdownx.betterem:
smart_enable: all
- pymdownx.caret
- pymdownx.smartsymbols
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.details
- pymdownx.superfences
plugins:
- search:
lang: de
separator: '[\s\-\.]'
- macros:
module_name: docs/macros
extra:
javadoc_url: https://zeichenmaschine.xyz/docs/
javadoc_default_package: schule.ngb.zm

25
requirements.txt Normal file
View File

@@ -0,0 +1,25 @@
certifi==2022.9.24
charset-normalizer==2.1.1
click==8.1.3
ghp-import==2.1.0
idna==3.4
Jinja2==3.1.2
Markdown==3.3.7
MarkupSafe==2.1.1
mergedeep==1.3.4
mkdocs==1.4.1
mkdocs-macros-plugin==0.7.0
mkdocs-material==8.5.6
mkdocs-material-extensions==1.0.3
packaging==21.3
Pygments==2.13.0
pymdown-extensions==9.6
pyparsing==3.0.9
python-dateutil==2.8.2
PyYAML==6.0
pyyaml_env_tag==0.1
requests==2.28.1
six==1.16.0
termcolor==2.0.1
urllib3==1.26.12
watchdog==2.1.9

View File

@@ -4,6 +4,10 @@ import java.awt.*;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel; import java.awt.image.ColorModel;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/** /**
* Repräsentiert eine Farbe in der Zeichenmaschine. * Repräsentiert eine Farbe in der Zeichenmaschine.
@@ -108,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.
*/ */
@@ -117,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.
*/ */
@@ -127,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.
@@ -140,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.
@@ -156,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);
@@ -204,45 +208,100 @@ 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);
} }
public static Color parseString( String pColor ) { /**
pColor = pColor.toLowerCase().strip(); * Erstellt aus einem Farbnamen ein Farbobjekt.
if( pColor.contains("red") || pColor.contains("rot") ) { * <p>
return Color.RED.copy(); * Die gültigen Farbnamen können unter <a
} else if( pColor.contains("blue") || pColor.contains("blau") ) { * href="https://htmlcolors.com/color-names">https://htmlcolors.com/color-names</a>
return Color.BLUE.copy(); * nachgeschlagen werden.
} else if( pColor.contains("green") || pColor.contains("grün") || pColor.contains("gruen") ) { *
return Color.GREEN.copy(); * @param color Der Name einer Farbe.
} else if( pColor.contains("yellow") || pColor.contains("gelb") ) { * @return Ein Farbobjekt.
return Color.YELLOW.copy(); */
} else { public static Color parseString( String color ) {
return new Color(); color = color.toLowerCase().strip();
// Parse colornames file and return first match
try(
InputStream in = Color.class.getResourceAsStream("colornames.csv");
BufferedReader reader = new BufferedReader(new InputStreamReader(in))
) {
String line;
while( (line = reader.readLine()) != null ) {
String[] parts = line.split(",");
if( parts.length == 2 ) {
if( parts[0].equals(color) ) {
return Color.parseHexcode(parts[1]);
} }
} }
}
} catch( IOException ex ) {
// LOG?
}
return new Color();
}
/** /**
* 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("#") ) {
@@ -279,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 ) {
@@ -329,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);
} }
@@ -337,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.
@@ -484,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}.
*/ */

View File

@@ -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.

View File

@@ -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;
} }

View File

@@ -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,31 +218,117 @@ 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;
} }
} }
}
} }

View File

@@ -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.

View File

@@ -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 );
} }

View File

@@ -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);

View File

@@ -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");
if( iconUrl != null ) {
Image icon = ImageIO.read(iconUrl); Image icon = ImageIO.read(iconUrl);
// Dock Icon in macOS setzen // Dock Icon in macOS setzen
Taskbar taskbar = Taskbar.getTaskbar(); Taskbar taskbar = Taskbar.getTaskbar();
taskbar.setIconImage(icon); 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);

View File

@@ -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();

View File

@@ -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
*/ */

View File

@@ -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);

View File

@@ -0,0 +1,342 @@
algae green,#64e986
aliceblue,#f0f8ff
alien green,#6cc417
antiquewhite,#faebd7
aquamarine,#7fffd4
army brown,#827b60
ash gray,#666362
avocado green,#b2c248
aztech purple,#893bff
azure,#f0ffff
baby blue,#95b9c7
bashful pink,#c25283
basket ball orange,#f88158
battleship gray,#848482
bean red,#f75d59
bee yellow,#e9ab17
beer,#fbb117
beetle green,#4c787e
beige,#f5f5dc
black cat,#413839
black cow,#4c4646
black eel,#463e3f
black,#000000
blanchedalmond,#ffebcd
blonde,#fbf6d9
blood red,#7e3517
blossom pink,#f9b7ff
blue angel,#b7ceec
blue diamond,#4ee2ec
blue dress,#157dec
blue eyes,#1569c7
blue gray,#98afc7
blue green,#7bccb5
blue hosta,#77bfc7
blue ivy,#3090c7
blue jay,#2b547e
blue koi,#659ec7
blue lagoon,#8eebec
blue lotus,#6960ec
blue orchid,#1f45fc
blue ribbon,#306eff
blue whale,#342d7e
blue zircon,#57feff
blueberry blue,#0041c2
blush pink,#e6a9ec
blush red,#e56e94
brass,#b5a642
bright gold,#fdd017
bright neon pink,#f433ff
bronze,#cd7f32
brown bear,#835c3b
brown sugar,#e2a76f
bullet shell,#af9b60
burgundy,#8c001a
burlywood,#deb887
burnt pink,#c12267
butterfly blue,#38acec
cadillac pink,#e38aae
camel brown,#c19a6b
camouflage green,#78866b
cantaloupe,#ffa62f
caramel,#c68e17
carbon gray,#625d5d
carnation pink,#f778a1
celeste,#50ebec
champagne,#f7e7ce
charcoal,#34282c
chartreuse,#8afb17
cherry red,#c24641
chestnut red,#c34a2c
chestnut,#954535
chilli pepper,#c11b17
chocolate,#c85a17
cinnamon,#c58917
cloudy gray,#6d6968
clover green,#3ea055
cobalt blue,#0020c2
coffee,#6f4e37
columbia blue,#87afc7
construction cone orange,#f87431
cookie brown,#c7a317
copper,#b87333
coral blue,#afdcec
coral,#ff7f50
corn yellow,#fff380
cornflower blue,#6495ed
cornsilk,#fff8dc
cotton candy,#fcdfff
cranberry,#9f000f
cream,#ffffcc
crimson,#e238ec
crocus purple,#9172ec
crystal blue,#5cb3ff
cyan opaque,#92c7c7
cyan or aqua,#00ffff
dark carnation pink,#c12283
dark forest green,#254117
dark goldenrod,#af7817
dark orange,#f88017
dark orchid,#7d1b7e
dark salmon,#e18b6b
dark sea green,#8bb381
dark slate blue,#2b3856
dark slate grey,#25383c
dark turquoise,#3b9c9c
dark violet,#842dce
day sky blue,#82caff
deep peach,#ffcba4
deep pink,#f52887
deep sky blue,#3bb9ff
denim blue,#79baec
denim dark blue,#151b8d
desert sand,#edc9af
dimorphotheca magenta,#e3319d
dodger blue,#1589ff
dollar bill green,#85bb65
dragon green,#6afb92
dull purple,#7f525d
earth blue,#0000a0
eggplant,#614051
electric blue,#9afeff
emerald green,#5ffb17
fall leaf brown,#c8b560
fern green,#667c26
ferrari red,#f70d1a
fire engine red,#f62817
firebrick,#800517
flamingo pink,#f9a7b0
forest green,#4e9258
frog green,#99c68e
ginger brown,#c9be62
glacial blue ice,#368bc1
golden brown,#eac117
goldenrod,#edda74
granite,#837e7c
grape,#5e5a80
grapefruit,#dc381f
gray cloud,#b6b6b4
gray dolphin,#5c5858
gray goose,#d1d0ce
gray wolf,#504a4b
gray,#736f6e
grayish turquoise,#5e7d7e
green apple,#4cc417
green onion,#6aa121
green peas,#89c35c
green snake,#6cbb3c
green thumb,#b5eaaa
green yellow,#b1fb17
green,#00ff00
greenish blue,#307d7e
gunmetal,#2c3539
halloween orange,#e66c2c
harvest gold,#ede275
hazel green,#617c58
heliotrope purple,#d462ff
hot pink,#f660ab
hummingbird green,#7fe817
iceberg,#56a5ec
iguana green,#9cb071
indigo,#4b0082
iridium,#3d3c3a
jade green,#5efb6e
jasmine purple,#a23bec
jeans blue,#a0cfec
jellyfish,#46c7c7
jet gray,#616d7e
jungle green,#347c2c
kelly green,#4cc552
khaki rose,#c5908e
khaki,#ada96e
lapis blue,#15317e
lava red,#e42217
lavender blue,#e3e4fa
lavender pinocchio,#ebdde2
lawn green,#87f717
lemon chiffon,#fff8c6
light aquamarine,#93ffe8
light blue,#addfff
light coral,#e77471
light cyan,#e0ffff
light jade,#c3fdb8
light pink,#faafba
light salmon,#f9966b
light sea green,#3ea99f
light sky blue,#82cafa
light slate blue,#736aff
light slate gray,#6d7b8d
light slate,#ccffff
light steel blue,#728fce
lilac,#c8a2c8
lime green,#41a317
lipstick pink,#c48793
love red,#e41b17
lovely purple,#7f38ec
macaroni and cheese,#f2bb66
macaw blue green,#43bfc7
magenta,#ff00ff
mahogany,#c04000
mango orange,#ff8040
marble blue,#566d7e
maroon,#810541
mauve,#e0b0ff
medium aquamarine,#348781
medium forest green,#347235
medium orchid,#b048b5
medium purple,#8467d7
medium sea green,#306754
medium spring green,#348017
medium turquoise,#48cccd
medium violet red,#ca226b
metallic silver,#bcc6cc
midnight blue,#151b54
midnight,#2b1b17
milk white,#fefcff
mint green,#98ff98
mist blue,#646d7e
misty rose,#fbbbb9
moccasin,#827839
mocha,#493d26
mustard,#ffdb58
navy blue,#000080
nebula green,#59e817
neon pink,#f535aa
night,#0c090a
northern lights blue,#78c7c7
oak brown,#806517
ocean blue,#2b65ec
oil,#3b3131
orange gold,#d4a017
orange salmon,#c47451
pale blue lily,#cfecec
pale violet red,#d16587
papaya orange,#e56717
parchment,#ffffc2
pastel blue,#b4cfec
peach,#ffe5b4
pearl,#fdeef4
periwinkle,#e9cfec
pig pink,#fdd7e4
pine green,#387c44
pink bow,#c48189
pink bubblegum,#ffdfdd
pink cupcake,#e45e9d
pink daisy,#e799a3
pink lemonade,#e4287c
pink rose,#e7a1b0
pink,#faafbe
pistachio green,#9dc209
platinum,#e5e4e2
plum pie,#7d0541
plum purple,#583759
plum velvet,#7d0552
plum,#b93b8f
powder blue,#c6deff
puce,#7f5a58
pumpkin orange,#f87217
purple amethyst,#6c2dc7
purple daffodil,#b041ff
purple dragon,#c38ec7
purple flower,#a74ac7
purple haze,#4e387e
purple iris,#571b7e
purple jam,#6a287e
purple mimosa,#9e7bff
purple monster,#461b7e
purple sage bush,#7a5dc7
purple,#8e35ef
red dirt,#7f5217
red fox,#c35817
red wine,#990012
red,#ff0000
robin egg blue,#bdedff
rogue pink,#c12869
rose gold,#ecc5c0
rose,#e8adaa
rosy brown,#b38481
rosy finch,#7f4e52
royal blue,#2b60de
rubber ducky yellow,#ffd801
ruby red,#f62217
rust,#c36241
saffron,#fbb917
sage green,#848b79
salad green,#a1c935
sand,#c2b280
sandstone,#786d5f
sandy brown,#ee9a4d
sangria,#7e3817
sapphire blue,#2554c7
scarlet,#ff2400
school bus yellow,#e8a317
sea blue,#c2dfff
sea green,#4e8975
sea turtle green,#438d80
seashell,#fff5ee
seaweed green,#437c17
sedona,#cc6600
sepia,#7f462c
shamrock green,#347c17
shocking orange,#e55b3c
sienna,#8a4117
silk blue,#488ac7
sky blue,#6698ff
slate blue,#737ca1
slate gray,#657383
slime green,#bce954
smokey gray,#726e6d
spring green,#4aa02c
steel blue,#4863a0
stoplight go green,#57e964
sun yellow,#ffe87c
sunrise orange,#e67451
tan brown,#ece5b6
tangerine,#e78a61
taupe,#483c32
tea green,#ccfb5d
teal,#008080
thistle,#d2b9d3
tiffany blue,#81d8d0
tiger orange,#c88141
tron blue,#7dfdfe
tulip pink,#c25a7c
turquoise,#43c6db
tyrian purple,#c45aec
valentine red,#e55451
vampire gray,#565051
vanilla,#f3e5ab
velvet maroon,#7e354d
venom green,#728c00
viola purple,#7e587e
violet red,#f6358a
violet,#8d38c9
water,#ebf4fa
watermelon pink,#fc6c85
white,#ffffff
windows blue,#357ec7
wisteria purple,#c6aec7
wood,#966f33
yellow green,#52d017
yellow,#ffff00
zombie green,#54c571
1 algae green #64e986
2 aliceblue #f0f8ff
3 alien green #6cc417
4 antiquewhite #faebd7
5 aquamarine #7fffd4
6 army brown #827b60
7 ash gray #666362
8 avocado green #b2c248
9 aztech purple #893bff
10 azure #f0ffff
11 baby blue #95b9c7
12 bashful pink #c25283
13 basket ball orange #f88158
14 battleship gray #848482
15 bean red #f75d59
16 bee yellow #e9ab17
17 beer #fbb117
18 beetle green #4c787e
19 beige #f5f5dc
20 black cat #413839
21 black cow #4c4646
22 black eel #463e3f
23 black #000000
24 blanchedalmond #ffebcd
25 blonde #fbf6d9
26 blood red #7e3517
27 blossom pink #f9b7ff
28 blue angel #b7ceec
29 blue diamond #4ee2ec
30 blue dress #157dec
31 blue eyes #1569c7
32 blue gray #98afc7
33 blue green #7bccb5
34 blue hosta #77bfc7
35 blue ivy #3090c7
36 blue jay #2b547e
37 blue koi #659ec7
38 blue lagoon #8eebec
39 blue lotus #6960ec
40 blue orchid #1f45fc
41 blue ribbon #306eff
42 blue whale #342d7e
43 blue zircon #57feff
44 blueberry blue #0041c2
45 blush pink #e6a9ec
46 blush red #e56e94
47 brass #b5a642
48 bright gold #fdd017
49 bright neon pink #f433ff
50 bronze #cd7f32
51 brown bear #835c3b
52 brown sugar #e2a76f
53 bullet shell #af9b60
54 burgundy #8c001a
55 burlywood #deb887
56 burnt pink #c12267
57 butterfly blue #38acec
58 cadillac pink #e38aae
59 camel brown #c19a6b
60 camouflage green #78866b
61 cantaloupe #ffa62f
62 caramel #c68e17
63 carbon gray #625d5d
64 carnation pink #f778a1
65 celeste #50ebec
66 champagne #f7e7ce
67 charcoal #34282c
68 chartreuse #8afb17
69 cherry red #c24641
70 chestnut red #c34a2c
71 chestnut #954535
72 chilli pepper #c11b17
73 chocolate #c85a17
74 cinnamon #c58917
75 cloudy gray #6d6968
76 clover green #3ea055
77 cobalt blue #0020c2
78 coffee #6f4e37
79 columbia blue #87afc7
80 construction cone orange #f87431
81 cookie brown #c7a317
82 copper #b87333
83 coral blue #afdcec
84 coral #ff7f50
85 corn yellow #fff380
86 cornflower blue #6495ed
87 cornsilk #fff8dc
88 cotton candy #fcdfff
89 cranberry #9f000f
90 cream #ffffcc
91 crimson #e238ec
92 crocus purple #9172ec
93 crystal blue #5cb3ff
94 cyan opaque #92c7c7
95 cyan or aqua #00ffff
96 dark carnation pink #c12283
97 dark forest green #254117
98 dark goldenrod #af7817
99 dark orange #f88017
100 dark orchid #7d1b7e
101 dark salmon #e18b6b
102 dark sea green #8bb381
103 dark slate blue #2b3856
104 dark slate grey #25383c
105 dark turquoise #3b9c9c
106 dark violet #842dce
107 day sky blue #82caff
108 deep peach #ffcba4
109 deep pink #f52887
110 deep sky blue #3bb9ff
111 denim blue #79baec
112 denim dark blue #151b8d
113 desert sand #edc9af
114 dimorphotheca magenta #e3319d
115 dodger blue #1589ff
116 dollar bill green #85bb65
117 dragon green #6afb92
118 dull purple #7f525d
119 earth blue #0000a0
120 eggplant #614051
121 electric blue #9afeff
122 emerald green #5ffb17
123 fall leaf brown #c8b560
124 fern green #667c26
125 ferrari red #f70d1a
126 fire engine red #f62817
127 firebrick #800517
128 flamingo pink #f9a7b0
129 forest green #4e9258
130 frog green #99c68e
131 ginger brown #c9be62
132 glacial blue ice #368bc1
133 golden brown #eac117
134 goldenrod #edda74
135 granite #837e7c
136 grape #5e5a80
137 grapefruit #dc381f
138 gray cloud #b6b6b4
139 gray dolphin #5c5858
140 gray goose #d1d0ce
141 gray wolf #504a4b
142 gray #736f6e
143 grayish turquoise #5e7d7e
144 green apple #4cc417
145 green onion #6aa121
146 green peas #89c35c
147 green snake #6cbb3c
148 green thumb #b5eaaa
149 green yellow #b1fb17
150 green #00ff00
151 greenish blue #307d7e
152 gunmetal #2c3539
153 halloween orange #e66c2c
154 harvest gold #ede275
155 hazel green #617c58
156 heliotrope purple #d462ff
157 hot pink #f660ab
158 hummingbird green #7fe817
159 iceberg #56a5ec
160 iguana green #9cb071
161 indigo #4b0082
162 iridium #3d3c3a
163 jade green #5efb6e
164 jasmine purple #a23bec
165 jeans blue #a0cfec
166 jellyfish #46c7c7
167 jet gray #616d7e
168 jungle green #347c2c
169 kelly green #4cc552
170 khaki rose #c5908e
171 khaki #ada96e
172 lapis blue #15317e
173 lava red #e42217
174 lavender blue #e3e4fa
175 lavender pinocchio #ebdde2
176 lawn green #87f717
177 lemon chiffon #fff8c6
178 light aquamarine #93ffe8
179 light blue #addfff
180 light coral #e77471
181 light cyan #e0ffff
182 light jade #c3fdb8
183 light pink #faafba
184 light salmon #f9966b
185 light sea green #3ea99f
186 light sky blue #82cafa
187 light slate blue #736aff
188 light slate gray #6d7b8d
189 light slate #ccffff
190 light steel blue #728fce
191 lilac #c8a2c8
192 lime green #41a317
193 lipstick pink #c48793
194 love red #e41b17
195 lovely purple #7f38ec
196 macaroni and cheese #f2bb66
197 macaw blue green #43bfc7
198 magenta #ff00ff
199 mahogany #c04000
200 mango orange #ff8040
201 marble blue #566d7e
202 maroon #810541
203 mauve #e0b0ff
204 medium aquamarine #348781
205 medium forest green #347235
206 medium orchid #b048b5
207 medium purple #8467d7
208 medium sea green #306754
209 medium spring green #348017
210 medium turquoise #48cccd
211 medium violet red #ca226b
212 metallic silver #bcc6cc
213 midnight blue #151b54
214 midnight #2b1b17
215 milk white #fefcff
216 mint green #98ff98
217 mist blue #646d7e
218 misty rose #fbbbb9
219 moccasin #827839
220 mocha #493d26
221 mustard #ffdb58
222 navy blue #000080
223 nebula green #59e817
224 neon pink #f535aa
225 night #0c090a
226 northern lights blue #78c7c7
227 oak brown #806517
228 ocean blue #2b65ec
229 oil #3b3131
230 orange gold #d4a017
231 orange salmon #c47451
232 pale blue lily #cfecec
233 pale violet red #d16587
234 papaya orange #e56717
235 parchment #ffffc2
236 pastel blue #b4cfec
237 peach #ffe5b4
238 pearl #fdeef4
239 periwinkle #e9cfec
240 pig pink #fdd7e4
241 pine green #387c44
242 pink bow #c48189
243 pink bubblegum #ffdfdd
244 pink cupcake #e45e9d
245 pink daisy #e799a3
246 pink lemonade #e4287c
247 pink rose #e7a1b0
248 pink #faafbe
249 pistachio green #9dc209
250 platinum #e5e4e2
251 plum pie #7d0541
252 plum purple #583759
253 plum velvet #7d0552
254 plum #b93b8f
255 powder blue #c6deff
256 puce #7f5a58
257 pumpkin orange #f87217
258 purple amethyst #6c2dc7
259 purple daffodil #b041ff
260 purple dragon #c38ec7
261 purple flower #a74ac7
262 purple haze #4e387e
263 purple iris #571b7e
264 purple jam #6a287e
265 purple mimosa #9e7bff
266 purple monster #461b7e
267 purple sage bush #7a5dc7
268 purple #8e35ef
269 red dirt #7f5217
270 red fox #c35817
271 red wine #990012
272 red #ff0000
273 robin egg blue #bdedff
274 rogue pink #c12869
275 rose gold #ecc5c0
276 rose #e8adaa
277 rosy brown #b38481
278 rosy finch #7f4e52
279 royal blue #2b60de
280 rubber ducky yellow #ffd801
281 ruby red #f62217
282 rust #c36241
283 saffron #fbb917
284 sage green #848b79
285 salad green #a1c935
286 sand #c2b280
287 sandstone #786d5f
288 sandy brown #ee9a4d
289 sangria #7e3817
290 sapphire blue #2554c7
291 scarlet #ff2400
292 school bus yellow #e8a317
293 sea blue #c2dfff
294 sea green #4e8975
295 sea turtle green #438d80
296 seashell #fff5ee
297 seaweed green #437c17
298 sedona #cc6600
299 sepia #7f462c
300 shamrock green #347c17
301 shocking orange #e55b3c
302 sienna #8a4117
303 silk blue #488ac7
304 sky blue #6698ff
305 slate blue #737ca1
306 slate gray #657383
307 slime green #bce954
308 smokey gray #726e6d
309 spring green #4aa02c
310 steel blue #4863a0
311 stoplight go green #57e964
312 sun yellow #ffe87c
313 sunrise orange #e67451
314 tan brown #ece5b6
315 tangerine #e78a61
316 taupe #483c32
317 tea green #ccfb5d
318 teal #008080
319 thistle #d2b9d3
320 tiffany blue #81d8d0
321 tiger orange #c88141
322 tron blue #7dfdfe
323 tulip pink #c25a7c
324 turquoise #43c6db
325 tyrian purple #c45aec
326 valentine red #e55451
327 vampire gray #565051
328 vanilla #f3e5ab
329 velvet maroon #7e354d
330 venom green #728c00
331 viola purple #7e587e
332 violet red #f6358a
333 violet #8d38c9
334 water #ebf4fa
335 watermelon pink #fc6c85
336 white #ffffff
337 windows blue #357ec7
338 wisteria purple #c6aec7
339 wood #966f33
340 yellow green #52d017
341 yellow #ffff00
342 zombie green #54c571

View File

@@ -147,6 +147,36 @@ class ColorTest {
@Test @Test
void parseHexcode() { void parseHexcode() {
Color c;
c = Color.parseHexcode("#f05025");
assertEquals(Color.RED, c);
c = Color.parseHexcode("#F8EF22");
assertEquals(Color.YELLOW, c);
c = Color.parseHexcode("#FF40ff");
assertEquals(new Color(255, 64, 255), c);
// TODO: Test hexcodes of length 3, 6 and 9
// TODO: Test malformed hexcodes
}
@Test
void parseString() {
Color c;
c = Color.parseString("red");
assertEquals(new Color(255, 0, 0), c);
c = Color.parseString("zombie green");
assertEquals(Color.parseHexcode("#54c571"), c);
c = Color.parseString("algae green");
assertEquals(new Color(100, 233, 134), c);
c = Color.parseString("light slate gray");
assertEquals(Color.parseHexcode("#6d7b8d"), c);
} }
@Test @Test
@@ -173,10 +203,6 @@ class ColorTest {
void HSLtoRGB() { void HSLtoRGB() {
} }
@Test
void testHSLtoRGB() {
}
@Test @Test
void copy() { void copy() {
} }