From e0dc0987df24548b267f3d29db553c67960b6827 Mon Sep 17 00:00:00 2001 From: Alparslan Bayramli Date: Mon, 16 Oct 2023 15:13:24 +0200 Subject: [PATCH] Initial sharing of project --- Aufbau.java | 22 + Aufbau2.java | 26 + Dreieck.java | 171 ++++ DreieckBesser.java | 26 + Ereignisbehandlung.java | 109 +++ Figur.java | 341 +++++++ Kreis.java | 166 ++++ KreisBesser.java | 25 + README.TXT | 24 + Rechteck.java | 170 ++++ RechteckBesser.java | 26 + Text.java | 193 ++++ Turtle.java | 342 +++++++ Zeichenfenster.java | 1864 +++++++++++++++++++++++++++++++++++++++ package.bluej | 170 ++++ 15 files changed, 3675 insertions(+) create mode 100644 Aufbau.java create mode 100644 Aufbau2.java create mode 100644 Dreieck.java create mode 100644 DreieckBesser.java create mode 100644 Ereignisbehandlung.java create mode 100644 Figur.java create mode 100644 Kreis.java create mode 100644 KreisBesser.java create mode 100644 README.TXT create mode 100644 Rechteck.java create mode 100644 RechteckBesser.java create mode 100644 Text.java create mode 100644 Turtle.java create mode 100644 Zeichenfenster.java create mode 100644 package.bluej diff --git a/Aufbau.java b/Aufbau.java new file mode 100644 index 0000000..9611366 --- /dev/null +++ b/Aufbau.java @@ -0,0 +1,22 @@ + +/** + * Baut im Konstruktor das Szenarium auf + * + * @author Albert Wiedemann + * @version 1.0 + */ +class Aufbau +{ + + /** + * Legt die benötigten Objekte an. + */ + Aufbau () + { + new KreisBesser(150, 150, 50, "rot"); + new DreieckBesser(200, 50, 60, 50, "grün"); + new RechteckBesser(100, 220, 200, 50, "grün"); + new RechteckBesser(270, 60, 130, 70, "blau"); + new DreieckBesser(350, 190, 70, 80, "rot"); + } +} diff --git a/Aufbau2.java b/Aufbau2.java new file mode 100644 index 0000000..82c282b --- /dev/null +++ b/Aufbau2.java @@ -0,0 +1,26 @@ + +import java.util.*; +/** + * Baut im Konstruktor das Szenarium auf + * + * @author Albert Wiedemann + * @version 1.0 + */ +class Aufbau2 +{ + /** der Zufallsgenerator */ + Random zufall; + + /** + * Legt die benötigten Objekte an. + */ + Aufbau2 () + { + zufall = new Random(); + new RechteckBesser(zufall.nextInt(400), zufall.nextInt(200), 200, 50, "grün"); + new RechteckBesser(zufall.nextInt(400), zufall.nextInt(200), 130, 70, "blau"); + new DreieckBesser(zufall.nextInt(400) + 50, zufall.nextInt(200), 60, 50, "grün"); + new DreieckBesser(zufall.nextInt(400) + 50, zufall.nextInt(200), 70, 80, "rot"); + new KreisBesser(zufall.nextInt(400) + 50, zufall.nextInt(150) + 50, 50, "rot"); + } +} diff --git a/Dreieck.java b/Dreieck.java new file mode 100644 index 0000000..db1914f --- /dev/null +++ b/Dreieck.java @@ -0,0 +1,171 @@ + +/** + * Wrapperklasse für ein Dreieck auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Dreieck +{ + /** x-Position der Spitze. */ + private int x; + /** y-Position der Spitze. */ + private int y; + /** Breite des umgebenden Rechtecks. */ + private int breite; + /** Höhe des umgebenden Rechtecks. */ + private int höhe; + /** Farbe des Dreiecks. */ + private String farbe; + /** Sichtbarkeit des Dreiecks. */ + private boolean sichtbar; + /** Drehwinkel (mathematisch positiver Drehsinn) des Dreiecks in Grad. */ + private int winkel; + /** Referenz auf das Delegate-Objekt. */ + Zeichenfenster.GrafikSymbol symbol; + + /** + * Der Konstruktor erzeugt das Delegate-Objekt + */ + Dreieck () + { + x = 60; + y = 10; + breite = 100; + höhe = 100; + farbe = "rot"; + sichtbar = true; + winkel = 0; + symbol = Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.dreieck); + symbol.PositionSetzen(x - breite / 2, y); + symbol.GrößeSetzen(breite, höhe); + symbol.FarbeSetzen(farbe); + symbol.SichtbarkeitSetzen(sichtbar); + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Position (der Spitze) des Dreiecks. + * @param x x-Position der Spitze + * @param y y-Position der Spitze + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x - breite / 2, y); + } + + /** + * Verschiebt das Dreieck um die angegebenen Werte. + * @param deltaX Verschiebung in x-Richtung + * @param deltaY Verschiebung in y-Richtung + */ + void Verschieben(int deltaX, int deltaY) + { + x += deltaX; + y += deltaY; + symbol.PositionSetzen(x - breite / 2, y); + } + + /** + * Dreht das Dreieck + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmass + */ + void Drehen(int grad) + { + winkel += grad; + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Größe des Dreiecks. + * @param breite (neue) Breite + * @param höhe (neue) Höhe + */ + void GrößeSetzen (int breite, int höhe) + { + this.breite = breite; + this.höhe = höhe; + symbol.GrößeSetzen(breite, höhe); + symbol.PositionSetzen(x - breite / 2, y); + } + + /** + * Setzt die Farbe des Dreiecks. + * Erlaubte Farben sind: + * "weiß", "weiss", "rot", "grün", "gruen", "blau", "gelb", + * "magenta", "cyan", "hellgelb", "hellgrün", "hellgruen", + * "orange", "braun", "grau", "schwarz" + * Alle anderen Eingaben werden auf die Farbe schwarz abgebildet. + * @param farbe (neue) Farbe + */ + void FarbeSetzen (String farbe) + { + this.farbe = farbe; + symbol.FarbeSetzen(farbe); + } + + /** + * Setzt den Drehwinkel des Dreiecks. + * Die Winkelangabe ist in Grad,positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn). + * @param winkel der (neue) Drehwinkel des Dreiecks + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit des Dreiecks ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Dreiecks + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt das Dreieck aus dem Zeichenfenster. + */ + void Entfernen () + { + symbol.Entfernen(); + } + + /** + * Bringt das Dreieck eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt das Dreieck in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt das Dreieck eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt das Dreieck in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } +} diff --git a/DreieckBesser.java b/DreieckBesser.java new file mode 100644 index 0000000..f729866 --- /dev/null +++ b/DreieckBesser.java @@ -0,0 +1,26 @@ + +/** + * Erlaubt das vollständige Anlegen im Konstruktor. + * + * @author Albert Wiedemann + * @version 1.0 + */ +class DreieckBesser extends Dreieck +{ + + /** + * Legt das Dreieck nach den gegebenen Daten an. + * @param x x-Position der Spitze + * @param y y-Position der Spitze + * @param breite Breite des Dreiecks + * @param höhe Höhe des Dreiecks + * @param farbe Farbe des Dreiecks + */ + DreieckBesser (int x, int y, int breite, int höhe, String farbe) + { + super(); + PositionSetzen(x, y); + GrößeSetzen(breite, höhe); + FarbeSetzen(farbe); + } +} diff --git a/Ereignisbehandlung.java b/Ereignisbehandlung.java new file mode 100644 index 0000000..8119639 --- /dev/null +++ b/Ereignisbehandlung.java @@ -0,0 +1,109 @@ +import java.awt.*; +import javax.swing.*; +import java.awt.event.*; + +/** + * Zugriff auf die Ereignisse einschließlich Taktgeber. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Ereignisbehandlung +{ + /** + * Der Konstruktor meldet den Taktgeber + * und die Eventlistener bei der Zeichenfläche an. + */ + Ereignisbehandlung () + { + Zeichenfenster.AktionsEmpfängerEintragen(new Zeichenfenster.AktionsEmpfaenger() + { + public void Ausführen () + { + TaktImpulsAusführen(); + } + + public void Taste (char taste) + { + TasteGedrückt(taste); + } + + public void SonderTaste (int taste) + { + SonderTasteGedrückt(taste); + } + + public void Geklickt (int x, int y, int anzahl) + { + MausGeklickt(x, y, anzahl); + } + }); + } + + /** + * Die eigentliche Aktionsmethode des Zeitgebers. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + */ + void TaktImpulsAusführen () + { + System.out.println ("Tick"); + } + + /** + * Zeitgeber starten. + */ + void Starten () + { + Zeichenfenster.TaktgeberStarten(); + } + + /** + * Zeitgeber anhalten. + */ + void Anhalten () + { + Zeichenfenster.TaktgeberStoppen(); + } + + /** + * Ablaufgeschwindigkeit des Zeitgebers einstellen. + * + * @param dauer: Angabe in Millisekunden + */ + void TaktdauerSetzen (int dauer) + { + Zeichenfenster.TaktdauerSetzen(dauer); + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Tasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste die gedrückte Taste + */ + void TasteGedrückt (char taste) + { + System. out. println ("Taste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Sondertasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste KeyCode der gedrückten Taste + */ + void SonderTasteGedrückt (int taste) + { + System. out. println ("Sondertaste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für einen Mausklick. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param x x-Position des Mausklicks + * @param y y-Position des Mausklicks + * @param anzahl Anzahl der aufeinanderfolgenden Mausklicks + */ + void MausGeklickt (int x, int y, int anzahl) + { + System. out. println ("Maus: (" + x + "|" + y + "), " + anzahl + " mal"); + } +} diff --git a/Figur.java b/Figur.java new file mode 100644 index 0000000..e100c62 --- /dev/null +++ b/Figur.java @@ -0,0 +1,341 @@ + +/** + * Wrapperklasse für die Turtle auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Figur +{ + /** x-Position der Figur. */ + private int x; + /** y-Position der Figur. */ + private int y; + /** Größe der Figur. */ + private int größe; + /** Farbe der Figur. */ + private String farbe; + /** Sichtbarkeit der Figur. */ + private boolean sichtbar; + /** Drehwinkel (mathemtisch positiver Drehsinn) der Turtle in Grad. */ + private int winkel; + /** Referenz auf das echte Figursymbol. */ + Zeichenfenster.FigurIntern symbol; + /** Referenz auf das Aktionsempfängerobjekt. */ + Zeichenfenster.AktionsEmpfaenger aktionsEmpfänger; + + /** + * Konstruktor der Figur + * Erzeugt eine Figur und versetzt sie in einen gültigen Startzustand. + */ + Figur () + { + symbol = (Zeichenfenster.FigurIntern) Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.figur); + symbol.SichtbarkeitSetzen(true); + x = symbol.x; + y = symbol.y; + winkel = symbol.winkel; + größe = symbol.b; + sichtbar = symbol.sichtbar; + aktionsEmpfänger = new Zeichenfenster.AktionsEmpfaenger() + { + public void Ausführen () + { + AktionAusführen(); + } + + public void Taste (char taste) + { + TasteGedrückt(taste); + } + + public void SonderTaste (int taste) + { + SonderTasteGedrückt(taste); + } + + public void Geklickt (int x, int y, int anzahl) + { + MausGeklickt(x, y, anzahl); + } + }; + Zeichenfenster.AktionsEmpfängerEintragen(aktionsEmpfänger); + } + + /** + * Methode wird aufgerufen, wenn die Figur handeln soll. + * Die vordefinierte Methode tut nichts. + */ + void AktionAusführen() + { + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Tasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste die gedrückte Taste + */ + void TasteGedrückt (char taste) + { + //System. out. println ("Taste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Sondertasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste KeyCode der gedrückten Taste + */ + void SonderTasteGedrückt (int taste) + { + //System. out. println ("Sondertaste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für einen Mausklick. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param x x-Position des Mausklicks + * @param y y-Position des Mausklicks + * @param anzahl Anzahl der aufeinanderfolgenden Mausklicks + */ + void MausGeklickt (int x, int y, int anzahl) + { + //System. out. println ("Maus: (" + x + "|" + y + "), " + anzahl + " mal"); + } + + /** + * Setzt die Position der Figur. + * @param x x-Position der Figur + * @param y y-Position der Figur + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x, y); + } + + /** + * Setzt die Größe des Figurensymbols. + * @param größe (neue) Größe + */ + void GrößeSetzen (int größe) + { + this.größe = größe; + symbol.GrößeSetzen(größe, größe); + } + + /** + * Setzt den Drehwinkel der Figur. + * Die Winkelangabe ist in Grad, positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn), d. h. + * 0˚: Figur schaut nach rechts, + * 90˚: Figur schaut nach oben, + * 180˚: Figur schaut nach links, + * 270˚bzw. -90˚: Figur schaut nach unten + * @param winkel der (neue) Drehwinkel der Figur + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit der Figur ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit der Figur + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt die Figur aus dem Zeichenfenster. + */ + void Entfernen () + { + Zeichenfenster.AktionsEmpfängerEntfernen(aktionsEmpfänger); + symbol.Entfernen(); + } + + /** + * Bringt die Figur eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt die Figur in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt die Figur eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt die Figur in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } + + /** + * Setzt die Figur wieder an ihre Ausgangsposition. + */ + void ZumStartpunktGehen() + { + symbol.ZumStartpunktGehen(); + x = symbol.x; + y = symbol.y; + winkel = symbol.winkel; + } + + /** + * Bewegt die Figur nach vorne. + * @param länge Anzahl der Längeneinheiten + */ + void Gehen(double länge) + { + symbol.Gehen(länge); + x = symbol.x; + y = symbol.y; + } + + /** + * Dreht die Figur + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmaß + */ + void Drehen(int grad) + { + symbol.Drehen(grad); + winkel = symbol.winkel; + } + + /** + * Gibt den aktuellen Winkel der Figur zurück. + * Die Winkelangabe ist in Grad, positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn), d. h. + * 0˚: Figur schaut nach rechts, + * 90˚: Figur schaut nach oben, + * 180˚: Figur schaut nach links, + * 270˚bzw. -90˚: Figur schaut nach unten + * @return Winkel im Gradmaß + */ + int WinkelGeben() + { + return winkel; + } + + /** + * Gibt die x-Koordinate der Figur zurück. + * @return x-Koordinate + */ + int XPositionGeben() + { + return x; + } + + /** + * Gibt die y-Koordinate der Figur zurück. + * @return y-Koordinate + */ + int YPositionGeben() + { + return y; + } + + /** + * Testet, ob die Figur eine Grafik-Figur berührt. + * @return true, wenn die Figur und eine Grafikfigur überlappen + */ + boolean Berührt () + { + return symbol.Berührt(); + } + + /** + * Testet, ob die Figur eine Grafik-Figur in der angegebenen Farbe berührt. + * @param farbe die Farbe, die die berührte Figur haben muss + * @return true, wenn die Figur und eine Grafikfigur in der angegebenen Farbe überlappen + */ + boolean Berührt (String farbe) + { + return symbol.Berührt(farbe); + } + + /** + * Testet, ob die Figur die angegebene Figur berührt. + * @param objekt das Objekt, das getestet werden soll + * @return true, wenn die Figur die angegebene Grafikfigur überlappen + */ + boolean Berührt (Object objekt) + { + return symbol.Berührt(objekt); + } + + /** + * Erzeugt ein neues, rechteckiges Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100x100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x x-Wert der linken oberen Ecke des Rechtecks + * @param y y-Wert der linken oberen Ecke des Rechtecks + * @param breite Breite des Rechtecks + * @param höhe Höhe des Rechtecks + * @param farbe (Füll-)Farbe des Rechtecks + */ + void FigurteilFestlegenRechteck (int x, int y, int breite, int höhe, String farbe) + { + symbol.FigurteilFestlegenRechteck(x, y, breite, höhe, farbe); + } + + /** + * Erzeugt ein neues, elliptisches Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100x100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x x-Wert der linken oberen Ecke des umgebenden Rechtecks der Ellipse + * @param y y-Wert der linken oberen Ecke des umgebenden Rechtecks der Ellipse + * @param breite Breite des umgebenden Rechtecks der Ellipse + * @param höhe Höhe des umgebenden Rechtecks der Ellipse + * @param farbe (Füll-)Farbe der Ellipse + */ + void FigurteilFestlegenEllipse (int x, int y, int breite, int höhe, String farbe) + { + symbol.FigurteilFestlegenEllipse(x, y, breite, höhe, farbe); + } + + /** + * Erzeugt ein neues, dreieckiges Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100x100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x1 x-Wert des ersten Punkts des Dreiecks + * @param y1 y-Wert des ersten Punkts des Dreiecks + * @param x2 x-Wert des zweiten Punkts des Dreiecks + * @param y2 y-Wert des zweiten Punkts des Dreiecks + * @param x3 x-Wert des dritten Punkts des Dreiecks + * @param y3 y-Wert des dritten Punkts des Dreiecks + * @param farbe (Füll)Farbe des Dreiecks + */ + void FigurteilFestlegenDreieck (int x1, int y1, int x2, int y2, int x3, int y3, String farbe) + { + symbol.FigurteilFestlegenDreieck(x1, y1, x2, y2, x3, y3, farbe); + } + + /** + * Löscht die Vereinbarung für die eigene Darstellung der Figur. + * Die Figur wird wieder durch die Originalfigur dargestellt. + */ + void EigeneFigurLöschen() + { + symbol.EigeneFigurLöschen(); + } +} diff --git a/Kreis.java b/Kreis.java new file mode 100644 index 0000000..5a8f89a --- /dev/null +++ b/Kreis.java @@ -0,0 +1,166 @@ + +/** + * Wrapperklasse für einen Kreis auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Kreis +{ + /** x-Position des Kreismittelpunktes. */ + private int x; + /** y-Position des Kreismittelpunktes. */ + private int y; + /** Radius des Kreises. */ + private int radius; + /** Farbe des Kreises. */ + private String farbe; + /** Sichtbarkeit des Kreises. */ + private boolean sichtbar; + /** Drehwinkel (mathematisch positiver Drehsinn) des Kreises in Grad. */ + private int winkel; + /** Referenz auf das Delegate-Objekt. */ + Zeichenfenster.GrafikSymbol symbol; + + /** + * Der Konstruktor erzeugt das Delegate-Objekt + */ + Kreis () + { + x = 60; + y = 60; + radius = 50; + farbe = "rot"; + sichtbar = true; + winkel = 0; + symbol = Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.kreis); + symbol.PositionSetzen(x - radius, y - radius); + symbol.GrößeSetzen(radius * 2, radius * 2); + symbol.FarbeSetzen(farbe); + symbol.SichtbarkeitSetzen(sichtbar); + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Position (des Mittelpunkts) des Kreises. + * @param x x-Position des Mittelpunkts + * @param y y-Position des Mittelpunkts + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x - radius, y - radius); + } + + /** + * Verschiebt den Kreis um die angegebenen Werte. + * @param deltaX Verschiebung in x-Richtung + * @param deltaY Verschiebung in y-Richtung + */ + void Verschieben(int deltaX, int deltaY) + { + x += deltaX; + y += deltaY; + symbol.PositionSetzen(x - radius, y - radius); + } + + /** + * Dreht den Kreis + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmass + */ + void Drehen(int grad) + { + winkel += grad; + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt den Radius des Kreises. + * @param radius (neuer) Radius + */ + void RadiusSetzen (int radius) + { + this.radius = radius; + symbol.GrößeSetzen(radius * 2, radius * 2); + symbol.PositionSetzen(x - radius, y - radius); + } + + /** + * Setzt die Farbe des Kreises. + * Erlaubte Farben sind: + * "weiß", "weiss", "rot", "grün", "gruen", "blau", "gelb", + * "magenta", "cyan", "hellgelb", "hellgrün", "hellgruen", + * "orange", "braun", "grau", "schwarz" + * Alle anderen Eingaben werden auf die Farbe schwarz abgebildet. + * @param farbe (neue) Farbe + */ + void FarbeSetzen (String farbe) + { + this.farbe = farbe; + symbol.FarbeSetzen(farbe); + } + + /** + * Setzt den Drehwinkel des Kreises. + * Die Winkelangabe ist in Grad,positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn). + * @param winkel der (neue) Drehwinkel des Kreises + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit des Kreises ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Kreises + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt den Kreis aus dem Zeichenfenster. + */ + void Entfernen () + { + symbol.Entfernen(); + } + + /** + * Bringt den Kreis eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt den Kreis in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt den Kreis eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt den Kreis in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } +} diff --git a/KreisBesser.java b/KreisBesser.java new file mode 100644 index 0000000..839779e --- /dev/null +++ b/KreisBesser.java @@ -0,0 +1,25 @@ + +/** + * Erlaubt das vollständige Anlegen im Konstruktor. + * + * @author Albert Wiedemann + * @version 1.0 + */ +class KreisBesser extends Kreis +{ + + /** + * Legt den Kreis nach den gegebenen Daten an. + * @param x x-Position des Mittelpunkts + * @param y y-Position des Mittelpunkts + * @param radius Radius des Kreises + * @param farbe Farbe des Kreises + */ + KreisBesser (int x, int y, int radius, String farbe) + { + super(); + PositionSetzen(x, y); + RadiusSetzen(radius); + FarbeSetzen(farbe); + } +} diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..323235f --- /dev/null +++ b/README.TXT @@ -0,0 +1,24 @@ +Projektbezeichnung: +Grafikdokument + +Ziel: +Ein erstes Einstiegsprojekt in die Entwicklungsumgebung BlueJ. +Dient zur Wiederholung der Begriffe Klasse, Objekt, Attribut, Methode, etc. +aus dem Informatikunterricht der Unterstufe. + +Man kann verschiedene Figuren erzeugen, die mit ihrem zugehörigen Grafiksymbol +in einem Grafikfenster eingezeichnet werden. + +Diese Figuren können durch den Aufruf von Methoden interaktiv verändert werden. +Nach jedem Methodenaufruf wird das Grafiksymbol und damit die ganze Zeichnung +automatisch angepasst. + +Start des Projekts: +Erzeugen neuer Figur-Objekte über das Kontextmenü. + +Version: +1.0 + +Autor: +A. Wiedemann + diff --git a/Rechteck.java b/Rechteck.java new file mode 100644 index 0000000..9931e5c --- /dev/null +++ b/Rechteck.java @@ -0,0 +1,170 @@ + +/** + * Wrapperklasse für ein Rechteck auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Rechteck +{ + /** x-Position der linken oberen Ecke. */ + private int x; + /** y-Position der linken oberen Ecke. */ + private int y; + /** Breite des Rechtecks. */ + private int breite; + /** Höhe des Rechtecks. */ + private int höhe; + /** Farbe des Rechtecks. */ + private String farbe; + /** Sichtbarkeit des Rechtecks. */ + private boolean sichtbar; + /** Drehwinkel (mathematisch positiver Drehsinn) des Rechtecks in Grad. */ + private int winkel; + /** Referenz auf das Delegate-Objekt. */ + Zeichenfenster.GrafikSymbol symbol; + + /** + * Der Konstruktor erzeugt das Delegate-Objekt + */ + Rechteck () + { + x = 10; + y = 10; + breite = 100; + höhe = 100; + farbe = "rot"; + sichtbar = true; + winkel = 0; + symbol = Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.rechteck); + symbol.PositionSetzen(x, y); + symbol.GrößeSetzen(breite, höhe); + symbol.FarbeSetzen(farbe); + symbol.SichtbarkeitSetzen(sichtbar); + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Position (der linken oberen Ecke) des Rechtecks. + * @param x x-Position der linken oberen Ecke + * @param y y-Position der linken oberen Ecke + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x, y); + } + + /** + * Verschiebt das Rechteck um die angegebenen Werte. + * @param deltaX Verschiebung in x-Richtung + * @param deltaY Verschiebung in y-Richtung + */ + void Verschieben(int deltaX, int deltaY) + { + x += deltaX; + y += deltaY; + symbol.PositionSetzen(x, y); + } + + /** + * Dreht das Rechteck + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmass + */ + void Drehen(int grad) + { + winkel += grad; + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Größe des Rechtecks. + * @param breite (neue) Breite + * @param höhe (neue) Höhe + */ + void GrößeSetzen (int breite, int höhe) + { + this.breite = breite; + this.höhe = höhe; + symbol.GrößeSetzen(breite, höhe); + } + + /** + * Setzt die Farbe des Rechtecks. + * Erlaubte Farben sind: + * "weiß", "weiss", "rot", "grün", "gruen", "blau", "gelb", + * "magenta", "cyan", "hellgelb", "hellgrün", "hellgruen", + * "orange", "braun", "grau", "schwarz" + * Alle anderen Eingaben werden auf die Farbe schwarz abgebildet. + * @param farbe (neue) Farbe + */ + void FarbeSetzen (String farbe) + { + this.farbe = farbe; + symbol.FarbeSetzen(farbe); + } + + /** + * Setzt den Drehwinkel des Rechtecks. + * Die Winkelangabe ist in Grad,positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn). + * @param winkel der (neue) Drehwinkel des Rechtecks + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit des Rechtecks ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Rechtecks + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt das Rechteck aus dem Zeichenfenster. + */ + void Entfernen () + { + symbol.Entfernen(); + } + + /** + * Bringt das Rechteck eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt das Rechteck in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt das Rechteck eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt das Rechteck in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } +} diff --git a/RechteckBesser.java b/RechteckBesser.java new file mode 100644 index 0000000..f98f471 --- /dev/null +++ b/RechteckBesser.java @@ -0,0 +1,26 @@ + +/** + * Erlaubt das vollständige Anlegen im Konstruktor. + * + * @author Albert Wiedemann + * @version 1.0 + */ +class RechteckBesser extends Rechteck +{ + + /** + * Legt das Rechteck nach den gegebenen Daten an. + * @param x x-Position der linken oberen Ecke + * @param y y-Position der linken oberen Ecke + * @param breite Breite des Rechtecks + * @param höhe Höhe des Rechtecks + * @param farbe Farbe des Rechtecks + */ + RechteckBesser (int x, int y, int breite, int höhe, String farbe) + { + super(); + PositionSetzen(x, y); + GrößeSetzen(breite, höhe); + FarbeSetzen(farbe); + } +} diff --git a/Text.java b/Text.java new file mode 100644 index 0000000..8a4c660 --- /dev/null +++ b/Text.java @@ -0,0 +1,193 @@ + +/** + * Wrapperklasse für einen Text auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Text +{ + /** x-Position der linken Seite der Grundlinie. */ + private int x; + /** y-Position der Grundlinie. */ + private int y; + /** Farbe des Textes. */ + private String farbe; + /** Sichtbarkeit des Textes. */ + private boolean sichtbar; + /** Drehwinkel (mathematisch positiver Drehsinn) des Textes in Grad. */ + private int winkel; + /** Größe des Textes in Punkten. */ + private int textgröße; + + /** Referenz auf das Delegate-Objekt. */ + private Zeichenfenster.TextIntern symbol; + + /** + * Der Konstruktor erzeugt das Delegate-Objekt + */ + Text () + { + x = 10; + y = 10; + farbe = "schwarz"; + sichtbar = true; + winkel = 0; + textgröße = 12; + symbol = (Zeichenfenster.TextIntern) Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.text); + symbol.PositionSetzen(x, y); + symbol.FarbeSetzen(farbe); + symbol.SichtbarkeitSetzen(sichtbar); + symbol.WinkelSetzen(winkel); + symbol.TextGrößeSetzen(textgröße); + } + + /** + * Setzt die Position (der Grundline) des Textes. + * @param x x-Position der linken Seite der Grundlinie + * @param y y-Position der Grundlinie + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x, y); + } + + /** + * Setzt den aktuellen Text. + * @param text der neue Text + */ + void TextSetzen (String text) + { + symbol.TextSetzen(text); + } + + /** + * Setzt die Größe des Textes. + * @param größe die (neue) Textgröße + */ + void TextGrößeSetzen (int größe) + { + textgröße = größe; + symbol.TextGrößeSetzen(größe); + } + + /** + * Vergrößert den Text. + */ + void TextVergrößern() + { + symbol.TextVergrößern(); + textgröße = (int) symbol.size; + } + + /** + * Verkleinert den Text. + */ + void TextVerkleinern() + { + symbol.TextVerkleinern(); + textgröße = (int) symbol.size; + } + + /** + * Verschiebt den Text um die angegebenen Werte. + * @param deltaX Verschiebung in x-Richtung + * @param deltaY Verschiebung in y-Richtung + */ + void Verschieben(int deltaX, int deltaY) + { + x += deltaX; + y += deltaY; + symbol.PositionSetzen(x, y); + } + + /** + * Dreht den Text + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmass + */ + void Drehen(int grad) + { + winkel += grad; + symbol.WinkelSetzen(winkel); + } + + /** + * Setzt die Farbe des Textes. + * Erlaubte Farben sind: + * "weiß", "weiss", "rot", "grün", "gruen", "blau", "gelb", + * "magenta", "cyan", "hellgelb", "hellgrün", "hellgruen", + * "orange", "braun", "grau", "schwarz" + * Alle anderen Eingaben werden auf die Farbe schwarz abgebildet. + * @param farbe (neue) Farbe + */ + void FarbeSetzen (String farbe) + { + this.farbe = farbe; + symbol.FarbeSetzen(farbe); + } + + /** + * Setzt den Drehwinkel des Textes. + * Die Winkelangabe ist in Grad,positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn). + * @param winkel der (neue) Drehwinkel des Textes + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit des Textes ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Textes + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt den Text aus dem Zeichenfenster. + */ + void Entfernen () + { + symbol.Entfernen(); + } + + /** + * Bringt den Text eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt den Text in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt den Text eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt den Text in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } +} diff --git a/Turtle.java b/Turtle.java new file mode 100644 index 0000000..b0815f5 --- /dev/null +++ b/Turtle.java @@ -0,0 +1,342 @@ + +/** + * Wrapperklasse für die Turtle auf der Zeichenfläche. + * + * @author Albert Wiedemann + * @version 1.0 + */ +public class Turtle +{ + /** x-Position der Turtle. */ + private int x; + /** y-Position der Turtle. */ + private int y; + /** Größe der Turtle. */ + private int größe; + /** Farbe der Turtle. */ + private String farbe; + /** Sichtbarkeit der Turtles. */ + private boolean sichtbar; + /** Drehwinkel (mathemtisch positiver Drehsinn) der Turtle in Grad. */ + private int winkel; + /**Stiftposition*/ + private boolean stiftUnten; + /** Referenz auf das echte Turtlesybol. */ + Zeichenfenster.TurtleIntern symbol; + /** Referenz auf das Aktionsempfängerobjekt. */ + Zeichenfenster.AktionsEmpfaenger aktionsEmpfänger; + + /** + * Konstruktor der Turtle + * Erzeugt eine Turtle und versetzt sie in einen gültigen Startzustand. + */ + Turtle () + { + symbol = (Zeichenfenster.TurtleIntern) Zeichenfenster.SymbolErzeugen(Zeichenfenster.SymbolArt.turtle); + symbol.SichtbarkeitSetzen(true); + x = symbol.x; + y = symbol.y; + winkel = symbol.winkel; + größe = symbol.b; + stiftUnten = symbol.stiftUnten; + sichtbar = symbol.sichtbar; + aktionsEmpfänger = new Zeichenfenster.AktionsEmpfaenger() + { + public void Ausführen () + { + AktionAusführen(); + } + + public void Taste (char taste) + { + TasteGedrückt(taste); + } + + public void SonderTaste (int taste) + { + SonderTasteGedrückt(taste); + } + + public void Geklickt (int x, int y, int anzahl) + { + MausGeklickt(x, y, anzahl); + } + }; + Zeichenfenster.AktionsEmpfängerEintragen(aktionsEmpfänger); + } + + /** + * Methode wird aufgerufen, wenn die Turtle handeln soll. + * Die vordefinierte Methode tut nichts. + */ + void AktionAusführen() + { + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Tasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste die gedrückte Taste + */ + void TasteGedrückt (char taste) + { + //System. out. println ("Taste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für gedrückte Sondertasten. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param taste KeyCode der gedrückten Taste + */ + void SonderTasteGedrückt (int taste) + { + //System. out. println ("Sondertaste: " + taste); + } + + /** + * Die eigentliche Aktionsmethode für einen Mausklick. + *
Muss bei Bedarf von einer Unterklasse überschrieben werden. + * @param x x-Position des Mausklicks + * @param y y-Position des Mausklicks + * @param anzahl Anzahl der aufeinanderfolgenden Mausklicks + */ + void MausGeklickt (int x, int y, int anzahl) + { + System. out. println ("Maus: (" + x + "|" + y + "), " + anzahl + " mal"); + } + + /** + * Setzt die Position der Turtle. + * @param x x-Position der Turtle + * @param y y-Position der Turtle + */ + void PositionSetzen(int x, int y) + { + this.x = x; + this.y = y; + symbol.PositionSetzen(x, y); + } + + /** + * Setzt die Größe des Turtlesymbols. + * @param größe (neue) Größe + */ + void GrößeSetzen (int größe) + { + this.größe = größe; + symbol.GrößeSetzen(größe, größe); + } + + /** + * Setzt die Farbe der Linie. + * Erlaubte Farben sind: + * "weiß", "weiss", "rot", "grün", "gruen", "blau", "gelb", + * "magenta", "cyan", "hellgelb", "hellgrün", "hellgruen", + * "orange", "braun", "grau", "schwarz" + * Alle anderen Eingaben werden auf die Farbe schwarz abgebildet. + * @param farbe (neue) Farbe + */ + void FarbeSetzen (String farbe) + { + this.farbe = farbe; + symbol.FarbeSetzen(farbe); + } + + /** + * Setzt den Drehwinkel der Turtle. + * Die Winkelangabe ist in Grad, positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn), d. h. + * 0˚: Turtle schaut nach rechts, + * 90˚: Turtle schaut nach oben, + * 180˚: Turtle schaut nach links, + * 270˚bzw. -90˚: Turtle schaut nach unten + * @param winkel der (neue) Drehwinkel der Turtle + */ + void WinkelSetzen (int winkel) + { + this.winkel = winkel; + symbol.WinkelSetzen(winkel); + } + + /** + * Schaltet die Sichtbarkeit der Turtle ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit der Turtle + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + symbol.SichtbarkeitSetzen(sichtbar); + } + + /** + * Entfernt die Turtle aus dem Zeichenfenster. + */ + void Entfernen () + { + Zeichenfenster.AktionsEmpfängerEntfernen(aktionsEmpfänger); + symbol.Entfernen(); + } + + /** + * Bringt die Turtle eine Ebene nach vorn. + */ + void NachVornBringen () + { + symbol.NachVornBringen(); + } + + /** + * Bringt die Turtle in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + symbol.GanzNachVornBringen(); + } + + /** + * Bringt die Turtle eine Ebene nach hinten. + */ + void NachHintenBringen () + { + symbol.NachHintenBringen(); + } + + /** + * Bringt die Turtle in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + symbol.GanzNachHintenBringen(); + } + + /** + * Setzt die Turtle wieder an ihre Ausgangsposition. + */ + void ZumStartpunktGehen() + { + symbol.ZumStartpunktGehen(); + x = symbol.x; + y = symbol.y; + winkel = symbol.winkel; + } + + /** + * Bewegt die Turtle nach vorne. + * @param länge Anzahl der Längeneinheiten + */ + void Gehen(double länge) + { + symbol.Gehen(länge); + x = symbol.x; + y = symbol.y; + } + + /** + * Dreht die Turtle + * @param grad Drehwinkel (mathematisch positiver Drehsinn) im Gradmaß + */ + void Drehen(int grad) + { + symbol.Drehen(grad); + winkel = symbol.winkel; + } + + /** + * Versetzt Zeichenfläche und Turtle in den Ausgangszustand + */ + void Löschen() + { + symbol.Löschen(); + } + + /** + * Turtle wechselt in den Modus "nicht zeichnen" + */ + void StiftHeben() + { + symbol.StiftHeben(); + stiftUnten = false; + } + + /** + * Turtle wechselt in den Modus "zeichnen" + */ + void StiftSenken() + { + symbol.StiftSenken(); + stiftUnten = true; + } + + /** + * Gibt den aktuellen Winkel der Turtle zurück. + * Die Winkelangabe ist in Grad, positive Werte drehen gegen den Uhrzeigersinn, + * negative Werte drehen im Uhrzeigersinn (mathematisch positiver Drehsinn), d. h. + * 0˚: Turtle schaut nach rechts, + * 90˚: Turtle schaut nach oben, + * 180˚: Turtle schaut nach links, + * 270˚bzw. -90˚: Turtle schaut nach unten + * @return Winkel im Gradmass + */ + int WinkelGeben() + { + return winkel; + } + + /** + * Gibt die x-Koordinate der Turtle zurück + * @return x-Koordinate + */ + int XPositionGeben() + { + return x; + } + + /** + * Gibt die y-Koordinate der Turtle zurück + * @return y-Koordinate + */ + int YPositionGeben() + { + return y; + } + + /** + * Schaltet die Sichtbarkeit des Turtlesymbols ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Turtlesymbols + */ + void SichtbarkeitFürSymbolSetzen (boolean sichtbar) + { + symbol.SichtbarkeitFürSymbolSetzen(sichtbar); + } + + /** + * Testet, ob die Turtle eine Figur berührt. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur sind + */ + boolean Berührt () + { + return symbol.Berührt(); + } + + /** + * Testet, ob die Turtle eine Figur in der angegebenen Farbe berührt. + * @param farbe die Farbe, die die berührte Figur haben muss. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur in der angegebenen Farbe sind + */ + boolean Berührt (String farbe) + { + return symbol.Berührt(farbe); + } + + /** + * Testet, ob die Turtle die angegebene Figur berührt. + * @param objekt das Objekt, das getestet werden soll. + * @return true, wenn die Turtlekoordinaten innerhalb der angegebenen Grafikfigur sind + */ + boolean Berührt (Object objekt) + { + return symbol.Berührt(objekt); + } +} diff --git a/Zeichenfenster.java b/Zeichenfenster.java new file mode 100644 index 0000000..ecf129a --- /dev/null +++ b/Zeichenfenster.java @@ -0,0 +1,1864 @@ + +import java.awt.*; +import java.awt.geom.*; +import java.awt.event.*; +import java.awt.image.*; +import javax.swing.*; +import javax.swing.event.*; +import java.util.*; +/** + * Die Klasse stellt ein Fenster mit einer Malfläche zur Verfügung, + * auf der Objekte der Klassen Rechteck, Kreis und Dreieck sowie Turtle dargestellt + * werden können. + * Die Zeichenfläche wird beim ersten Anlegen eines Zeichenobjekts automatisch + * nach dem Muster Singleton angelegt. + * + * @author Albert Wiedemann + * @version 1.0 + */ +class Zeichenfenster +{ + /** Interface für die Aktionsausführung. */ + interface AktionsEmpfaenger + { + /** Methode wird vom Taktgeber aufgerufen. */ + void Ausführen(); + void Taste (char taste); + void SonderTaste (int taste); + void Geklickt (int x, int y, int anzahl); + } + + /** Aufzählung der erzeugbaren Objektarten. */ + static enum SymbolArt {kreis, dreieck, rechteck, turtle, figur, text;}; + + /** Einziges Objekt der Zeichenfläche. */ + private static Zeichenfenster zeichenfläche = null; + + /** Fenster für die Zeichenfläche. */ + private JFrame fenster; + /** Die eigentliche Darstellungskomponente. */ + private JComponent malfläche; + /** Stop-Knopf für den Taktgeber. */ + private JButton stop; + /** Start-Knopf für den Taktgeber. */ + private JButton start; + /** Einsteller für die Taktrate*/ + private JSlider slider; + /** Feld aller zu zeichnenden Objekte. */ + private ArrayList alleSymbole; + /** Feld aller zu zeichnenden Objekte. */ + private ArrayList aktionsEmpfänger; + /** Timerobjekt für die zentrale Zeitverwaltung */ + private javax.swing.Timer timer; + + /** + * Legt das Fenster und die Malfläche an + */ + private Zeichenfenster () + { + alleSymbole = new ArrayList(); + aktionsEmpfänger = new ArrayList(); + fenster = new JFrame("Zeichenfenster"); + fenster.setLocation(50, 50); + fenster.setSize(800, 600); + fenster.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); //Close-Button kann nicht versteckt oder abgestellt werden. + + malfläche = new JComponent() + { + public void paint (Graphics g) + { + g.setColor(new Color (230, 230, 230)); + g.fillRect(0, 0, getWidth() - 1, getHeight() - 1); + synchronized (malfläche) + { + for (GrafikSymbol s: alleSymbole) + { + if (s.sichtbar) + { + s.Zeichnen(g); + } + } + } + } + }; + malfläche.setOpaque(true); + malfläche.addMouseListener(new MouseAdapter () + { + /** + * Gibt den Ort eines Mouseclicks an die eigentliche Aktionsmethode weiter. + * @param e das zugrestellte Ereignis + */ + public void mousePressed(MouseEvent e) + { + malfläche.requestFocus(); + ArrayList empfänger = new ArrayList(aktionsEmpfänger); + for (AktionsEmpfaenger em: empfänger) + { + em.Geklickt(e.getX(), e.getY(), e.getClickCount()); + } + } + } + ); + malfläche.addKeyListener(new KeyAdapter () + { + /** + * Gibt die Taste an die eigentliche Aktionsmethode weiter. + * @param e das zugestellte Ereignis + */ + public void keyPressed(KeyEvent e) + { + ArrayList empfänger = new ArrayList(aktionsEmpfänger); + if ((int) e.getKeyChar() == KeyEvent.CHAR_UNDEFINED) + { + switch (e.getKeyCode()) + { + case KeyEvent.VK_ENTER: + for (AktionsEmpfaenger em: empfänger) + { + em.Taste((char) KeyEvent.VK_ENTER); + } + break; + default: + for (AktionsEmpfaenger em: empfänger) + { + em.SonderTaste(e.getKeyCode()); + } + } + } + else + { + for (AktionsEmpfaenger em: empfänger) + { + em.Taste(e.getKeyChar()); + } + } + } + } + ); + malfläche.addComponentListener(new ComponentAdapter() + { + /** + * Setzt die Hintegrundbilder aller Turtle auf die neue Größe. + */ + public void componentResized​(ComponentEvent e) + { + for (GrafikSymbol s: alleSymbole) + { + if (s instanceof TurtleIntern) + { + ((TurtleIntern) s).NeueGrößeSetzen(); + } + } + } + } + ); + fenster.add(malfläche, BorderLayout.CENTER); + JPanel panel = new JPanel(); + panel.setMinimumSize(new Dimension(200, 60)); + panel.setSize(200,60); + panel.setVisible(true); + panel.setLayout(new GridLayout(1, 2)); + JPanel panel2 = new JPanel(); + panel2.setMinimumSize(new Dimension(100, 60)); + panel2.setSize(100,60); + panel2.setVisible(true); + panel2.setLayout(new GridLayout(1, 1)); + stop = new JButton(); + start = new JButton(); + start.setLocation(10, 10); + start.setSize(80, 30); + start.setText("Start"); + start.setVisible(true); + start.addActionListener(new ActionListener () + { + public void actionPerformed (ActionEvent evt) + { + TaktgeberStartenIntern(); + malfläche.requestFocus(); + } + } + ); + panel2.add(start); + stop.setLocation(100, 10); + stop.setSize(80, 30); + stop.setText("Stop"); + stop.setVisible(true); + stop.setEnabled(false); + stop.addActionListener(new ActionListener () + { + public void actionPerformed (ActionEvent evt) + { + TaktgeberStoppenIntern(); + malfläche.requestFocus(); + } + } + ); + panel2.add(stop); + panel.add(panel2); + slider = new JSlider(0, 1000, 100); + slider.setLocation(190, 10); + slider.setSize(160, 40); + slider.setMinimumSize(new Dimension(160, 40)); + slider.setPreferredSize(new Dimension(160, 40)); + slider.setMajorTickSpacing(100); + slider.setPaintTicks(true); + slider.setPaintLabels(true); + slider.setValue(1000); + slider.addChangeListener(new ChangeListener() + { + public void stateChanged​(ChangeEvent e) + { + timer.setDelay(slider.getValue()); + malfläche.requestFocus(); + } + } + ); + panel.add(slider); + + fenster.add(panel, BorderLayout.SOUTH); + fenster.setVisible(true); + malfläche.requestFocus(); + + timer = new javax.swing.Timer (1000, new ActionListener () + { + /** + * Vom Timer aufgerufen. + * Erzeugt den nächsten Taktimpuls + * @param evt der Timerevent + */ + public void actionPerformed (ActionEvent evt) + { + ArrayList empfänger = new ArrayList(aktionsEmpfänger); + for (AktionsEmpfaenger e: empfänger) + { + e.Ausführen(); + } + } + } + ); + } + + /** + * Meldet die aktuelle Breite der Malfläche. + * @returns Breite der Malfläche + */ + static int MalflächenBreiteGeben() + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + return zeichenfläche.malfläche.getWidth(); + } + + /** + * Meldet die aktuelle Höhe der Malfläche. + * @returns Höhe der Malfläche + */ + static int MalflächenHöheGeben() + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + return zeichenfläche.malfläche.getHeight(); + } + + /** + * Trägt einen neuen Aktionsempfänger ein. + * @param neu der neue Aktionsempfänger + */ + static void AktionsEmpfängerEintragen(AktionsEmpfaenger neu) + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + zeichenfläche.aktionsEmpfänger.add(neu); + } + + /** + * Löscht einen Aktionsempfänger aus der Liste. + * @param alt der zu löschende Aktionsempfänger + */ + static void AktionsEmpfängerEntfernen(AktionsEmpfaenger alt) + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + zeichenfläche.aktionsEmpfänger.remove(alt); + } + + /** + * Erzeugt ein neues darzustelledes Symbol. + * Die möglichen Symbole sind im Aufzählungstyp SymbolArt beschrieben. + * @param art Art des zu erzeugenden Symbols. + * @return Referenz auf das Delegate-Objekt. + */ + static GrafikSymbol SymbolErzeugen (SymbolArt art) + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + return zeichenfläche.SymbolAnlegen(art); + } + + /** + * Startet den Taktgeber. + */ + static void TaktgeberStarten () + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + zeichenfläche.TaktgeberStartenIntern(); + } + + /** + * Stoppt den Taktgeber. + */ + static void TaktgeberStoppen () + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + zeichenfläche.TaktgeberStoppenIntern(); + } + + /** + * Ablaufgeschwindigkeit des Zeitgebers einstellen. + * + * @param dauer: Angabe in Millisekunden + */ + static void TaktdauerSetzen (int dauer) + { + if (zeichenfläche == null) + { + zeichenfläche = new Zeichenfenster(); + } + zeichenfläche.slider.setValue(dauer < 0 ? 0 : (dauer > 1000 ? 1000: dauer)); + } + + /** + * Erzeugt das neue Symbol tatsächlich. + * @param art Art des zu erzeugenden Symbols. + * @return Referenz auf das Delegate-Objekt. + */ + private GrafikSymbol SymbolAnlegen (SymbolArt art) + { + GrafikSymbol neu = null; + switch (art) + { + case rechteck: + neu = new RechteckIntern(); + break; + case kreis: + neu = new EllipseIntern(); + break; + case dreieck: + neu = new DreieckIntern(); + break; + case turtle: + neu = new TurtleIntern(); + break; + case figur: + neu = new FigurIntern(); + break; + case text: + neu = new TextIntern(); + break; + } + synchronized (zeichenfläche.malfläche) + { + zeichenfläche.alleSymbole.add(neu); + } + malfläche.repaint(); + return neu; + } + + /** + * Startet den Taktgeber. + */ + private void TaktgeberStartenIntern() + { + start.setEnabled(false); + stop.setEnabled(true); + timer.start(); + } + + /** + * Stoppt den Taktgeber. + */ + private void TaktgeberStoppenIntern() + { + start.setEnabled(true); + stop.setEnabled(false); + timer.stop(); + } + + /** + * Oberklasse für alle verfügbaren Grafiksymbole. + * Alle Grafiksymbole werden über ihr umgebendes Rechteck beschrieben. + */ + abstract class GrafikSymbol + { + /** x-Position der linken oberen Ecke. */ + protected int x; + /** y-Position der linken oberen Ecke. */ + protected int y; + /** Breite des umgebenden Rechtecks. */ + protected int b; + /** Höhe des umgebenden Rechtecks. */ + protected int h; + /** Farbe des Symbols. */ + protected Color c; + /** Sichtbarkeit des Symbols. */ + protected boolean sichtbar; + /** Drehwinkel (mathematisch positiver Drehsinn) des Symbols. */ + protected int winkel; + /** Die Form des Grafiksymbols. */ + protected Area form; + /** Farbe Hellgelb. */ + protected final Color hellgelb = new Color(255,255,128); + /** Farbe Hellgrün. */ + protected final Color hellgrün = new Color(128,255,128); + /** Farbe Orange. */ + protected final Color orange = new Color(255,128,0); + /** Farbe Braun. */ + protected final Color braun = new Color(128,64,0); + + /** + * Der Konstruktor erzeugt ein rotes Symbol in der linken oberen Ecke des Fensters. + */ + GrafikSymbol() + { + x = 10; + y = 10; + b = 100; + h = 100; + c = Color.RED; + sichtbar = true; + winkel = 0; + FormErzeugen(); + } + + /** + * Normiert den Winkel auf Werte im Bereich [0; 360[ + * @param winkel der Eingabewinkel + * @return der normierte Winkel + */ + int WinkelNormieren(int winkel) + { + while (winkel < 0) + { + winkel += 360; + } + return winkel % 360; + } + + /** + * Setzt die Position (der linken oberen Ecke) des Objekts. + * @param x x-Position der linken oberen Ecke + * @param y y-Position der linken oberen Ecke + */ + void PositionSetzen (int x, int y) + { + this.x = x; + this.y = y; + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Setzt die Größe des Objekts. + * @param breite (neue) Breite des Objekts + * @param höhe (neue) Höhe des Objekts + */ + void GrößeSetzen (int breite, int höhe) + { + b = breite; + h = höhe; + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Bestimmt die RGB-Farbe für den gegeben String. + * @param farbe die Farbe als String + * @return die Farbe als RGB-Farbe + */ + Color FarbeCodieren (String farbe) + { + farbe = farbe.toLowerCase(); + switch (farbe) + { + case "weiß": + case "weiss": + return Color.WHITE; + case "rot": + return Color.RED; + case "grün": + case "gruen": + return Color.GREEN; + case "blau": + return Color.BLUE; + case "gelb": + return Color.YELLOW; + case "magenta": + return Color.MAGENTA; + case "cyan": + return Color.CYAN; + case "hellgelb": + return hellgelb; + case "hellgrün": + case "hellgruen": + return hellgrün; + case "orange": + return orange; + case "braun": + return braun; + case "grau": + return Color.GRAY; + case "schwarz": + return Color.BLACK; + default: + return Color.BLACK; + } + } + + /** + * Setzt die Farbe des Objekts. + * @param farbe (neue) Farbe des Objekts + */ + void FarbeSetzen (String farbe) + { + FarbeSetzen(FarbeCodieren(farbe)); + } + + /** + * Setzt die Farbe des Objekts. + * @param c (neue) Farbe des Objekts + */ + void FarbeSetzen (Color c) + { + this.c = c; + zeichenfläche.malfläche.repaint(); + } + + /** + * Setzt die Sichtbarkeit des Objekts. + * @param sichtbar (neue) Sichtbarkeit des Objekts + */ + void SichtbarkeitSetzen (boolean sichtbar) + { + this.sichtbar = sichtbar; + zeichenfläche.malfläche.repaint(); + } + + /** + * Setzt den Drehwinkel des Objekts. + * @param winkel der (neue) Drehwinkel des Objekts + */ + void WinkelSetzen (int winkel) + { + this.winkel = WinkelNormieren(winkel); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Entfernt das Objekt aus dem Zeichenfenster. + */ + void Entfernen () + { + synchronized (zeichenfläche.malfläche) + { + zeichenfläche.alleSymbole.remove(this); + zeichenfläche.malfläche.repaint(); + } + } + + /** + * Bringt das Objekt eine Ebene nach vorn. + */ + void NachVornBringen () + { + synchronized (zeichenfläche.malfläche) + { + int index = zeichenfläche.alleSymbole.indexOf(this); + if (index < zeichenfläche.alleSymbole.size() - 1) + { + zeichenfläche.alleSymbole.set(index, zeichenfläche.alleSymbole.get(index + 1)); + zeichenfläche.alleSymbole.set(index + 1, this); + zeichenfläche.malfläche.repaint(); + } + } + } + + /** + * Bringt das Objekt in die vorderste Ebene. + */ + void GanzNachVornBringen () + { + synchronized (zeichenfläche.malfläche) + { + int index = zeichenfläche.alleSymbole.indexOf(this); + if (index < zeichenfläche.alleSymbole.size() - 1) + { + zeichenfläche.alleSymbole.remove(index); + zeichenfläche.alleSymbole.add(this); + zeichenfläche.malfläche.repaint(); + } + } + } + + /** + * Bringt das Objekt eine Ebene nach hinten. + */ + void NachHintenBringen () + { + synchronized (zeichenfläche.malfläche) + { + int index = zeichenfläche.alleSymbole.indexOf(this); + if (index > 0) + { + zeichenfläche.alleSymbole.set(index, zeichenfläche.alleSymbole.get(index - 1)); + zeichenfläche.alleSymbole.set(index - 1, this); + zeichenfläche.malfläche.repaint(); + } + } + } + + /** + * Bringt das Objekt in die hinterste Ebene. + */ + void GanzNachHintenBringen () + { + synchronized (zeichenfläche.malfläche) + { + int index = zeichenfläche.alleSymbole.indexOf(this); + if (index > 0) + { + zeichenfläche.alleSymbole.remove(index); + zeichenfläche.alleSymbole.add(0, this); + zeichenfläche.malfläche.repaint(); + } + } + } + + /** + * Testet, ob der angegebene Punkt innerhalb der Figur ist. + * @param x x-Koordinate des zu testenden Punktes + * @param y y-Koordinate des zu testenden Punktes + * @return wahr, wenn der Punkt innerhalb der Figur ist + */ + boolean IstInnerhalb (int x, int y) + { + return form.contains(x, y); + } + + /** + * Testet, ob die beiden Figuren überlappen. + * @param wen die andere Form + * @return wahr, wenn die beiden Formen überlappen. + */ + boolean Schneidet (Area wen) + { + Area area = new Area(form); + area.intersect (wen); + return !area.isEmpty(); + } + + /** + * Zeichnet das Objekt + * @param g das Grafikobjekt zum Zeichnen + */ + void Zeichnen(Graphics g) + { + g.setColor(c); + ((Graphics2D) g).fill(form); + } + + /** + * Berechnet den Drehwinkel gemäß den Konventionen des Graphik-Frameworks. + * Für Java: Winkel in Radians, positive Drehrichtng im Uhrzeiger. + * @param winkel: Der Winkel in Grad, mathematischer Drehsinn + * @return Winkel für Graphik-Framework + */ + double DrehwinkelGeben (int winkel) + { + return - Math.PI * winkel / 180.0; + } + + /** + * Erstellt die Form des Objekts. + */ + abstract void FormErzeugen(); + } + + /** + * Objekte dieser Klasse verwalten ein Rechteck. + */ + private class RechteckIntern extends GrafikSymbol + { + /** + * Erstellt die Form des Rechtecks. + */ + @Override void FormErzeugen() + { + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (winkel), this.x + b / 2, this.y + h / 2); + form = new Area(new Path2D.Double (new Rectangle2D.Double(this.x, this.y, b, h), a)); + } + } + + /** + * Objekte dieser Klasse verwalten eine Ellipse. + */ + private class EllipseIntern extends GrafikSymbol + { + /** + * Erstellt die Form der Ellipse. + */ + @Override void FormErzeugen() + { + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (winkel), this.x + b / 2, this.y + h / 2); + form = new Area(new Path2D.Double (new Ellipse2D.Double(this.x, this.y, b, h), a)); + } + } + + /** + * Objekte dieser Klasse verwalten ein Dreieck. + */ + private class DreieckIntern extends GrafikSymbol + { + /** + * Erstellt die Form des Dreiecks. + */ + @Override void FormErzeugen() + { + Polygon rand = new Polygon (new int [] {x + b / 2, x + b, x, x + b / 2}, + new int [] {y, y + h, y + h, y}, 4); + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (winkel), this.x + b / 2, this.y + h / 2); + form = new Area(new Path2D.Double (rand, a)); + } + } + + /** + * Objekte dieser Klasse verwalten einen Text. + */ + class TextIntern extends GrafikSymbol + { + /** Der aktuelle Text. */ + private String text; + /** Die aktuelle Textgröße. */ + float size; + + /** + * Belegt text und size mit Defaultwerten. + */ + TextIntern () + { + super(); + text = "Text"; + size = 12; + c = Color.black; + } + + /** + * Erstellt die Form des Textes. + * Dummy, legt ein leeres Area an. + */ + @Override void FormErzeugen() + { + form = new Area(); + } + + /** + * Testet, ob der angegebene Punkt innerhalb der Figur ist. + * @param x x-Koordinate des zu testenden Punktes + * @param y y-Koordinate des zu testenden Punktes + * @return falsch + */ + @Override boolean IstInnerhalb (int x, int y) + { + return false; + } + + /** + * Setzt den aktuellen Text. + * @param t der neue Text + */ + void TextSetzen (String t) + { + text = t; + zeichenfläche.malfläche.repaint(); + } + + /** + * Setzt die Größe des Textes. + */ + void TextGrößeSetzen (int größe) + { + size = größe; + zeichenfläche.malfläche.repaint(); + } + + /** + * Vergrößert den Text. + */ + void TextVergrößern() + { + if (size <= 10) + { + size += 1; + } + else if (size <= 40) + { + size += 2; + } + else + { + size += 4; + } + zeichenfläche.malfläche.repaint(); + } + + /** + * Verkleinert den Text. + */ + void TextVerkleinern() + { + if (size <= 10) + { + size -= 1; + } + else if (size <= 40) + { + size -= 2; + } + else + { + size -= 4; + } + if (size < 1) + { + size = 1; + } + zeichenfläche.malfläche.repaint(); + } + + /** + * Zeichnet das Objekt als Dreieck in der gegebenen Farbe. + * @param g das Grafikobjekt zum Zeichnen + */ + @Override void Zeichnen(Graphics g) + { + g.setColor(c); + Font f = g.getFont(); + Font f2 = f.deriveFont(size); + g.setFont(f2); + + if (winkel == 0) + { + g.drawString(text, x, y); + } + else + { + Graphics2D g2 = (Graphics2D) g; + AffineTransform alt = g2.getTransform(); + //g2.rotate(DrehwinkelGeben (winkel), x + b / 2, y + h / 2); + //g2.rotate(DrehwinkelGeben (winkel), x + text.length() * size / 4, y + size / 2); + Rectangle2D bounds = f2.getStringBounds(text, g2.getFontRenderContext()); + g2.rotate(DrehwinkelGeben (winkel), x + bounds.getWidth() / 2, y - bounds.getHeight() / 2); + g.drawString(text, x, y); + g2.setTransform(alt); + } + g.setFont(f); + } + } + + /** + * Oberklasse für alle Elemente einer Figur (Figur, Turtle). + */ + private abstract class FigurenElement + { + double xe; + double ye; + double breite; + double höhe; + Color c; + /** + * Zeichnet das Figurenelement. + * @param g das Grafikobjekt + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + abstract void ElementZeichnen(Graphics2D g, double größe, int x, int y); + + /** + * Fügt den Pfadteil deiser Komponente zum umgebenden Pfad hinzu. + * @param p der Gesamtpfad + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + abstract void ElementZuForm (Path2D.Double p, double größe, int x, int y); + } + + /** + * Ein rechteckiges Figurenelement. + */ + private class FigurenElementRechteck extends FigurenElement + { + /** + * Der Konstruktor speichert die Rahmendaten. + * @param x x-Koordinate der linken oberen Ecke des Rechtecks relativ zum Aufhängepunkt. + * @param y y-Koordinate der linken oberen Ecke des Rechtecks relativ zum Aufhängepunkt. + * @param breite Breite des Rechtecks + * @param höhe Höhe des Rechtecks + * @param c Farbe des Rechtecks + */ + FigurenElementRechteck (double x, double y, double breite, double höhe, Color c) + { + this.xe = x; + this.ye = y; + this.breite = breite; + this.höhe = höhe; + this.c = c; + } + + /** + * Zeichnet das Figurenelement. + * @param g das Grafikobjekt + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZeichnen(Graphics2D g, double größe, int x, int y) + { + g.setColor(c); + g.fill(new Rectangle2D.Double (x+größe*xe/100.0, y+größe*ye/100.0, größe*breite/100.0, größe*höhe/100.0)); + } + + /** + * Fügt den Pfadteil dieser Komponente zum umgebenden Pfad hinzu. + * @param p der Gesamtpfad + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZuForm (Path2D.Double p, double größe, int x, int y) + { + p.append(new Rectangle2D.Double (x+größe*xe/100.0, y+größe*ye/100.0, größe*breite/100.0, größe*höhe/100.0), false); + } + } + + /** + * Ein elliptisches Figurenelement. + */ + private class FigurenElementEllipse extends FigurenElement + { + /** + * Der Konstruktor speichert die Rahmendaten. + * @param x x-Koordinate der linken oberen Ecke des umgebenden Rechtecks relativ zum Aufhängepunkt. + * @param y y-Koordinate der linken oberen Ecke des umgebenden Rechtecks relativ zum Aufhängepunkt. + * @param breite Breite der Ellipse + * @param höhe Höhe der Ellipse + * @param c Farbe der Ellipse + */ + FigurenElementEllipse (double x, double y, double breite, double höhe, Color c) + { + this.xe = x; + this.ye = y; + this.breite = breite; + this.höhe = höhe; + this.c = c; + } + + /** + * Zeichnet das Figurenelement. + * @param g das Grafikobjekt + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZeichnen(Graphics2D g, double größe, int x, int y) + { + g.setColor(c); + g.fill(new Ellipse2D.Double (x+größe*xe/100.0, y+größe*ye/100.0, größe*breite/100.0, größe*höhe/100.0)); + } + + /** + * Fügt den Pfadteil dieser Komponente zum umgebenden Pfad hinzu. + * @param p der Gesamtpfad + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZuForm (Path2D.Double p, double größe, int x, int y) + { + p.append(new Ellipse2D.Double (x+größe*xe/100.0, y+größe*ye/100.0, größe*breite/100.0, größe*höhe/100.0), false); + } + } + + /** + * Ein Figurenelement begrenzt durch das angegebene Polygon. + */ + private class FigurenElementPolygon extends FigurenElement + { + /** Das Polygonobjekt */ + private Polygon poly; + + /** + * Der Konstruktor speichert die Rahmendaten. + * @param x x-Koordinaten der Stützpunkte des Polygons relativ zum Aufhängepunkt. + * @param y y-Koordinaten der Stützpunkte des Polygons relativ zum Aufhängepunkt. + * @param c Farbe der Polygonfläche + */ + FigurenElementPolygon (int [] x, int[] y, Color c) + { + int anz = x.length <= y.length ? x.length : y.length; + poly = new Polygon (x, y, anz); + Rectangle2D bounds = poly.getBounds2D(); + xe = bounds.getX(); + ye = bounds.getY(); + breite = bounds.getWidth(); + höhe = bounds.getHeight(); + this.c = c; + } + + /** + * Zeichnet das Figurenelement. + * @param g das Grafikobjekt + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZeichnen(Graphics2D g, double größe, int x, int y) + { + g.setColor(c); + AffineTransform at = new AffineTransform(größe/100.0, 0, 0, größe/100.0, x, y); + g.fill(new Path2D.Double (poly, at)); + } + + /** + * Fügt den Pfadteil dieser Komponente zum umgebenden Pfad hinzu. + * @param p der Gesamtpfad + * @param größe die aktuelle Größe der Figur + * @param x die x-Koordinate des Aufhängepunkts der Figur + * @param y die y-Koordinate des Aufhängepunkts der Figur + */ + @Override void ElementZuForm (Path2D.Double p, double größe, int x, int y) + { + AffineTransform at = new AffineTransform(größe/100.0, 0, 0, größe/100.0, x, y); + Path2D.Double p2 = new Path2D.Double (poly, at); + p2.closePath(); + p2.setWindingRule(Path2D.WIND_EVEN_ODD); + p.append(p2, false); + } + } + + /** + * Das Objekt dieser Klasse zeichnet den Weg der Turtle. + */ + class TurtleIntern extends GrafikSymbol + { + private class LinienElement + { + /** x-Koordinate des Startpunktes. */ + private double xStart; + /** y-Koordinate des Startpunktes. */ + private double yStart; + /** x-Koordinate des Endpunktes. */ + private double xEnde; + /** y-Koordinate des Endpunktes. */ + private double yEnde; + /** Farbe des LinienElements. */ + private Color c; + + LinienElement (double xStart, double yStart, double xEnde, double yEnde, Color c) + { + this.xStart = xStart; + this.yStart = yStart; + this.xEnde = xEnde; + this.yEnde = yEnde; + this.c = c; + } + + void Zeichnen (Graphics2D g) + { + g.setColor(c); + g.draw(new Line2D.Double (xStart, yStart, xEnde, yEnde)); + } + } + + /** + * Verwaltet das Hintergrundfenster für die Turtlezeichnung. + */ + private class HintergrundBild + { + /** Das aktuelle Hintergrundbild. */ + private BufferedImage bild; + /** Das zugehörige Zeichenobjekt. */ + private Graphics2D g; + + /** + * Der Konstruktor legt das Bild in der Größe der Zeichenfläche an. + */ + HintergrundBild() + { + bild = new BufferedImage(Zeichenfenster.MalflächenBreiteGeben(), Zeichenfenster.MalflächenBreiteGeben(), BufferedImage.TYPE_INT_ARGB); + g = bild.createGraphics(); + g.setColor(new Color (0, 0, 0, 0)); + g.fillRect(0, 0, bild.getWidth(), bild.getHeight()); + } + + /** + * Zeichent die angegebe Linie in das Bild. + * @param linie das zu zeichnende Linienelement. + */ + void LinieZeichnen(LinienElement linie) + { + linie.Zeichnen(g); + } + + /** + * Zeichnet das Bild in das angegebene Zeichenobjekt. + * @param wohin Zeichenobjekt + */ + void BildZeichnen (Graphics2D wohin) + { + wohin.drawImage(bild, null, 0, 0); + } + } + + /** Genaue x-Koordinate der Turtle. */ + double xD; + /** Genaue y-Koordinate der Turtle. */ + double yD; + /** Startkoordinate der Turtle. */ + private int homeX; + /** Startkoordinate der Turtle. */ + private int homeY; + /** Startwinkel der Turtle. */ + private int homeWinkel; + /** Stiftposition. */ + boolean stiftUnten; + /** Die Sichtbarkeit des Turtle-Symbols. */ + private boolean symbolSichtbar; + /** Linienelemente. */ + private ArrayList linien; + /** Standardfigur für Turtle. */ + private LinkedList standardFigur; + /** Das Hintergrundbild für die Linien. */ + private HintergrundBild hintergrund; + + /** + * Legt die Turtle mit Startpunkt (100|200) in Richtung 0˚ an. + */ + TurtleIntern () + { + super (); + x = 100; + y = 200; + xD = x; + yD = y; + h = 40; + b = 40; + homeX=x; + homeY=y; + homeWinkel=winkel; + c = Color.black; + stiftUnten = true; + symbolSichtbar = true; + linien = new ArrayList(); + hintergrund = new HintergrundBild(); + standardFigur = new LinkedList(); + StandardfigurErzeugen(); + FormErzeugen(); + } + + /** + * Baut die Standardfigur aus den Elementen auf. + */ + private void StandardfigurErzeugen() + { + //Kopf + standardFigur.add(new FigurenElementEllipse(50, -12.5, 25, 25, Color.GREEN)); + //Beine + standardFigur.add(new FigurenElementEllipse(22.5, -32.5, 12.5, 17.5, Color.GREEN)); + standardFigur.add(new FigurenElementEllipse(40.0, -32.5, 12.5, 17.5, Color.GREEN)); + standardFigur.add(new FigurenElementEllipse(22.5, 15.0, 12.5, 17.5, Color.GREEN)); + standardFigur.add(new FigurenElementEllipse(40.0, 15.0, 12.5, 17.5, Color.GREEN)); + //Augen + standardFigur.add(new FigurenElementRechteck(67.5, -10.0, 5.0, 7.5, c)); + standardFigur.add(new FigurenElementRechteck(67.5, 2.5, 5.0, 7.5, c)); + //Schwanz + standardFigur.add(new FigurenElementEllipse(0, -3.75, 25, 7.5, c)); + //Rumpf + standardFigur.add(new FigurenElementEllipse(7.5, -23.75, 57.5, 47.5, braun)); + } + + /** + * Passt das Hintergrundbild an eine neue Größe der Zeichenfläche an. + */ + void NeueGrößeSetzen() + { + hintergrund = new HintergrundBild(); + for (LinienElement l: linien) + { + hintergrund.LinieZeichnen(l); + } + } + + /** + * Erstellt die Form der Turtle. + */ + @Override void FormErzeugen() + { + Area area = new Area(); + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (winkel), this.x, this.y); + double größe = h > b ? b : h; + if (standardFigur != null) + { + synchronized (standardFigur) + { + for (FigurenElement e: standardFigur) + { + Path2D.Double p = new Path2D.Double(); + e.ElementZuForm(p, größe, x, y); + area.add( new Area(new Path2D.Double (p, a))); + } + } + + } + form = area; + } + + /** + * Setzt die Position (der linken oberen Ecke) des Objekts. + * @param x x-Position der linken oberen Ecke + * @param y y-Position der linken oberen Ecke + */ + @Override void PositionSetzen (int x, int y) + { + super.PositionSetzen (x, y); + xD = x; + yD = y; + } + + /** + * Setzt die Turtle wieder an ihre Ausgangsposition. + */ + void ZumStartpunktGehen() + { + x = homeX; + y = homeY; + xD = x; + yD = y; + winkel = homeWinkel; + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Bewegt die Turtle nach vorne. + * @param länge Anzahl der Längeneinheiten + */ + void Gehen(double länge) + { + double neuX = xD + Math.cos(DrehwinkelGeben (winkel)) * länge; + double neuY = yD + Math.sin(DrehwinkelGeben (winkel)) * länge; + if (stiftUnten) + { + synchronized (this) + { + LinienElement l = new LinienElement(xD, yD, neuX, neuY, c); + linien.add (l); + hintergrund.LinieZeichnen (l); + } + } + xD = neuX; + yD = neuY; + x =(int) Math.round(xD); + y =(int) Math.round(yD); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Dreht die Turtle + * @param grad Drehwinkel im Gradmass + */ + void Drehen(int grad) + { + winkel = WinkelNormieren(winkel + grad); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Versetzt Zeichenfläche und Turtle in den Ausgangszustand + */ + void Löschen() + { + linien.clear(); + hintergrund = new HintergrundBild(); + ZumStartpunktGehen(); + } + + /** + * Turtle wechselt in den Modus "nicht zeichnen" + */ + void StiftHeben() + { + stiftUnten = false; + } + + /** + * Turtle wechselt in den Modus "zeichnen" + */ + void StiftSenken() + { + stiftUnten = true; + } + + /** + * Schaltet die Sichtbarkeit des Turtlesymbols ein oder aus. + * Erlaubte Parameterwerte: true, false + * @param sichtbar (neue) Sichtbarkeit des Turtlesymbols + */ + void SichtbarkeitFürSymbolSetzen (boolean sichtbar) + { + symbolSichtbar = sichtbar; + zeichenfläche.malfläche.repaint(); + } + + /** + * Testet, ob der angegebene Punkt innerhalb der Figur ist. + * @param x x-Koordinate des zu testenden Punktes + * @param y y-Koordinate des zu testenden Punktes + * @return wahr, wenn der Punkt innerhalb der Figur ist + */ + + /** + * Testet, ob die Turtle eine (sichtbare) Figur berührt. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur sind + */ + boolean Berührt () + { + for (GrafikSymbol g: zeichenfläche.alleSymbole) + { + if ((g != this) && g.IstInnerhalb(x, y) && g.sichtbar && (!(g instanceof TurtleIntern) || ((TurtleIntern) g).symbolSichtbar)) + { + return true; + } + } + return false; + } + + /** + * Testet, ob die Turtle eine (sichtbare) Figur in der angegebenen Farbe berührt. + * Bei Überlappungen + * @param farbe die Farbe, die die berührte Figur haben muss. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur in der angegebenen Farbe sind + */ + boolean Berührt (String farbe) + { + Color c2 = FarbeCodieren(farbe); + boolean ok = false; + for (GrafikSymbol g: zeichenfläche.alleSymbole) + { + if ((g != this) && g.IstInnerhalb(x, y) && g.sichtbar) + { + if (g instanceof TurtleIntern) + { + TurtleIntern t = (TurtleIntern) g; + if (t.symbolSichtbar) + { + for (FigurenElement e: t.standardFigur) + { + Path2D.Double p = new Path2D.Double(); + double größe = t.h > t.b ? t.b : t.h; + e.ElementZuForm(p, größe, t.x, t.y); + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (t.winkel), t.x, t.y); + p = new Path2D.Double (p, a); + if (p.contains(x, y)) + { + ok = c2.equals(e.c); + } + } + } + } + else if (g instanceof FigurIntern) + { + FigurIntern t = (FigurIntern) g; + LinkedList figur = ((t.eigeneFigur == null) || (t.eigeneFigur.size() == 0)) ? t.standardFigur : t.eigeneFigur; + for (FigurenElement e: figur) + { + Path2D.Double p = new Path2D.Double(); + double größe = t.h > t.b ? t.b : t.h; + e.ElementZuForm(p, größe, t.x, t.y); + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (t.winkel), t.x, t.y); + p = new Path2D.Double (p, a); + if (p.contains(x, y)) + { + ok = c2.equals(e.c); + } + } + } + else + { + ok = ok || c2.equals(g.c); + } + } + } + return ok; + } + + /** + * Testet, ob die Turtle die (sichtbare, ) angegebene Figur berührt. + * @param object das Objekt, das getestet werden soll. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur in der angegebenen Farbe sind + */ + boolean Berührt (Object object) + { + GrafikSymbol s = null; + if (object instanceof Rechteck) + { + s = ((Rechteck) object).symbol; + } + else if (object instanceof Dreieck) + { + s = ((Dreieck) object).symbol; + } + else if (object instanceof Kreis) + { + s = ((Kreis) object).symbol; + } + else if (object instanceof Turtle) + { + s = ((Turtle) object).symbol; + } + else if (object instanceof Figur) + { + s = ((Figur) object).symbol; + } + return (s != null) && (s != this) && s.IstInnerhalb(x, y) && s.sichtbar && (!(s instanceof TurtleIntern) || ((TurtleIntern) s).symbolSichtbar); + } + + /** + * Zeichnet das Objekt als Dreieck in der gegebenen Farbe. + * @param g das Grafikobjekt zum Zeichnen + */ + @Override void Zeichnen(Graphics g) + { + Graphics2D g2 = (Graphics2D) g; + synchronized (this) + { + hintergrund.BildZeichnen(g2); + } + + if (symbolSichtbar) + { + g.setColor(Color.black); + double größe = h > b ? b : h; + AffineTransform alt = g2.getTransform(); + g2.rotate(DrehwinkelGeben (winkel), x, y); + if (standardFigur != null) + { + synchronized (standardFigur) + { + for (FigurenElement e: standardFigur) + { + e.ElementZeichnen(g2, größe, x, y); + } + } + } + g2.setTransform(alt); + } + } + } + + /** + * Das Objekt dieser Klasse ist ein in der Gestalt definierbarer Akteur. + */ + class FigurIntern extends GrafikSymbol + { + + /** Genaue x-Koordinate der Figur. */ + double xD; + /** Genaue y-Koordinate der Figur. */ + double yD; + /** Startkoordinate der Figur. */ + private int homeX; + /** Startkoordinate der Figur. */ + private int homeY; + /** Startwinkel der Figur. */ + private int homeWinkel; + /** Eigene Figur für Figur. */ + private LinkedList eigeneFigur; + /** Standardfigur für Figur. */ + private LinkedList standardFigur; + + /** + * Legt die Figur mit Startpunkt (100|200) in Richtung 0˚ an. + */ + FigurIntern () + { + super (); + x = 100; + y = 200; + xD = x; + yD = y; + h = 40; + b = 40; + homeX=x; + homeY=y; + homeWinkel=winkel; + c = Color.black; + eigeneFigur = new LinkedList(); + standardFigur = new LinkedList(); + StandardfigurErzeugen(); + FormErzeugen(); + } + + /** + * Baut die Standardfigur aus den Elementen auf. + */ + private void StandardfigurErzeugen() + { + int[] x = new int [] {-50, 50, -50}; + int[] y = new int [] {-50, 0, 50}; + standardFigur.add (new FigurenElementPolygon (x, y, Color.yellow)); + standardFigur.add(new FigurenElementEllipse(-10, -10, 20, 20, Color.blue)); + } + + /** + * Erstellt die Form der Figur. + */ + @Override void FormErzeugen() + { + Area area = new Area(); + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (winkel), this.x, this.y); + double größe = h > b ? b : h; + if (standardFigur != null) + { + LinkedList figur = ((eigeneFigur == null) || (eigeneFigur.size() == 0)) ? standardFigur : eigeneFigur; + synchronized (figur) + { + for (FigurenElement e: figur) + { + Path2D.Double p = new Path2D.Double(); + e.ElementZuForm(p, größe, x, y); + area.add(new Area(new Path2D.Double (p, a))); + } + } + + } + form = area; + } + + /** + * Setzt die Position (der Mitte) des Objekts. + * @param x x-Position der Mitte + * @param y y-Position der Mitte + */ + @Override void PositionSetzen (int x, int y) + { + super.PositionSetzen (x, y); + xD = x; + yD = y; + } + + /** + * Setzt die Figur wieder an ihre Ausgangsposition. + */ + void ZumStartpunktGehen() + { + x = homeX; + y = homeY; + xD = x; + yD = y; + winkel = homeWinkel; + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Bewegt die Figur nach vorne. + * @param länge Anzahl der Längeneinheiten + */ + void Gehen(double länge) + { + double neuX = xD + Math.cos(DrehwinkelGeben (winkel)) * länge; + double neuY = yD + Math.sin(DrehwinkelGeben (winkel)) * länge; + xD = neuX; + yD = neuY; + x =(int) Math.round(xD); + y =(int) Math.round(yD); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Dreht die Figur + * @param grad Drehwinkel im Gradmass + */ + void Drehen(int grad) + { + winkel = WinkelNormieren(winkel + grad); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Testet, ob die Figur eine (sichtbare) Grafik-Figur berührt. + * @return true, wenn die Figurkoordinaten innerhalb einer Grafikfigur sind + */ + boolean Berührt () + { + for (GrafikSymbol g: zeichenfläche.alleSymbole) + { + if ((g != this) && g.Schneidet(form) && g.sichtbar && (!(g instanceof TurtleIntern) || ((TurtleIntern) g).symbolSichtbar)) + { + return true; + } + } + return false; + } + + /** + * Testet, ob die Figur eine (sichtbare) Grafik-Figur in der angegebenen Farbe berührt. + * Bei Überlappungen + * @param farbe die Farbe, die die berührte Figur haben muss. + * @return true, wenn die Figurkoordinaten innerhalb einer Grafikfigur in der angegebenen Farbe sind + */ + boolean Berührt (String farbe) + { + Color c2 = FarbeCodieren(farbe); + boolean ok = false; + for (GrafikSymbol g: zeichenfläche.alleSymbole) + { + if ((g != this) && g.Schneidet(form) && g.sichtbar) + { + if (g instanceof TurtleIntern) + { + TurtleIntern t = (TurtleIntern) g; + if (t.symbolSichtbar) + { + Area[] areas = new Area [t.standardFigur.size()]; + Color[] colors = new Color [t.standardFigur.size()]; + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (t.winkel), t.x, t.y); + int pos = 0; + for (FigurenElement e: t.standardFigur) + { + Path2D.Double p = new Path2D.Double(); + double größe = t.h > t.b ? t.b : t.h; + e.ElementZuForm(p, größe, t.x, t.y); + p = new Path2D.Double (p, a); + areas [pos] = new Area(p); + colors[pos] = e.c; + for (int i = pos - 1; i >= 0;i--) + { + areas[i].subtract(areas[pos]); + } + pos += 1; + } + for (int i = 0; i < areas.length; i++) + { + if (Schneidet(areas[i]) && (c2.equals(colors[i]))) + { + ok = true; + } + } + } + } + else if (g instanceof FigurIntern) + { + FigurIntern t = (FigurIntern) g; + LinkedList figur = ((t.eigeneFigur == null) || (t.eigeneFigur.size() == 0)) ? t.standardFigur : t.eigeneFigur; + Area[] areas = new Area [figur.size()]; + Color[] colors = new Color [figur.size()]; + AffineTransform a = new AffineTransform(); + a.rotate(DrehwinkelGeben (t.winkel), t.x, t.y); + int pos = 0; + for (FigurenElement e: figur) + { + Path2D.Double p = new Path2D.Double(); + double größe = t.h > t.b ? t.b : t.h; + e.ElementZuForm(p, größe, t.x, t.y); + p = new Path2D.Double (p, a); + areas [pos] = new Area(p); + colors[pos] = e.c; + for (int i = pos - 1; i >= 0;i--) + { + areas[i].subtract(areas[pos]); + } + pos += 1; + } + for (int i = 0; i < areas.length; i++) + { + if (Schneidet(areas[i]) && (c2.equals(colors[i]))) + { + ok = true; + } + } + } + else + { + ok = ok || c2.equals(g.c); + } + } + } + return ok; + } + + /** + * Testet, ob die Figur die (sichtbare, ) angegebene Grafik-Figur berührt. + * @param object das Objekt, das getestet werden soll. + * @return true, wenn die Turtlekoordinaten innerhalb einer Grafikfigur in der angegebenen Farbe sind + */ + boolean Berührt (Object object) + { + GrafikSymbol s = null; + if (object instanceof Rechteck) + { + s = ((Rechteck) object).symbol; + } + else if (object instanceof Dreieck) + { + s = ((Dreieck) object).symbol; + } + else if (object instanceof Kreis) + { + s = ((Kreis) object).symbol; + } + else if (object instanceof Turtle) + { + s = ((Turtle) object).symbol; + } + else if (object instanceof Figur) + { + s = ((Figur) object).symbol; + } + return (s != null) && (s != this) && s.Schneidet(form) && s.sichtbar && (!(s instanceof TurtleIntern) || ((TurtleIntern) s).symbolSichtbar); + } + + /** + * Erzeugt ein neues, rechteckiges Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x x-Wert der linken oberen Ecke des Rechtecks + * @param y y-Wert der linken oberen Ecke des Rechtecks + * @param breite Breite des Rechtecks + * @param höhe Höhe des Rechtecks + * @param farbe (Füll)Farbe des Rechtecks + */ + void FigurteilFestlegenRechteck (int x, int y, int breite, int höhe, String farbe) + { + synchronized (eigeneFigur) + { + eigeneFigur.add(new FigurenElementRechteck(x, y, breite, höhe, FarbeCodieren(farbe))); + } + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Erzeugt ein neues, elliptisches Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x x-Wert der linken oberen Ecke des umgebenden Rechtecks der Ellipse + * @param y y-Wert der linken oberen Ecke des umgebenden Rechtecks der Ellipse + * @param breite Breite des umgebenden Rechtecks der Ellipse + * @param höhe Höhe des umgebenden Rechtecks der Ellipse + * @param farbe (Füll)Farbe der Ellipse + */ + void FigurteilFestlegenEllipse (int x, int y, int breite, int höhe, String farbe) + { + synchronized (eigeneFigur) + { + eigeneFigur.add(new FigurenElementEllipse(x, y, breite, höhe, FarbeCodieren(farbe))); + } + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Erzeugt ein neues, dreieckiges Element einer eigenen Darstellung der Figur. + * Alle Werte beziehen sich auf eine Figur der Größe 100 und den Koordinaten (0|0) in der Mitte des Quadrats + * @param x1 x-Wert des ersten Punkts des Dreiecks + * @param y1 y-Wert des ersten Punkts des Dreiecks + * @param x2 x-Wert des zweiten Punkts des Dreiecks + * @param y2 y-Wert des zweiten Punkts des Dreiecks + * @param x3 x-Wert des dritten Punkts des Dreiecks + * @param y3 y-Wert des dritten Punkts des Dreiecks + * @param farbe (Füll)Farbe der Ellipse + */ + void FigurteilFestlegenDreieck (int x1, int y1, int x2, int y2, int x3, int y3, String farbe) + { + synchronized (eigeneFigur) + { + int[] x = new int [] {x1, x2, x3}; + int[] y = new int [] {y1, y2, y3}; + eigeneFigur.add(new FigurenElementPolygon(x, y, FarbeCodieren(farbe))); + } + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Löscht die Vereinbarung für die eigene Darstellung Figur. + * Die Figur wird wieder durch die Originalfigur dargestellt. + */ + void EigeneFigurLöschen() + { + eigeneFigur.clear(); + FormErzeugen(); + zeichenfläche.malfläche.repaint(); + } + + /** + * Zeichnet das Objekt als Dreieck in der gegebenen Farbe. + * @param g das Grafikobjekt zum Zeichnen + */ + @Override void Zeichnen(Graphics g) + { + Graphics2D g2 = (Graphics2D) g; + // Outline + g.setColor(Color.black); + Stroke stAlt = g2.getStroke(); + g2.setStroke(new BasicStroke(3.0f)); + g2.draw(form); + g2.setStroke(stAlt); + // Füllung + double größe = h > b ? b : h; + AffineTransform alt = g2.getTransform(); + g2.rotate(DrehwinkelGeben (winkel), x, y); + if (standardFigur != null) + { + LinkedList figur = ((eigeneFigur == null) || (eigeneFigur.size() == 0)) ? standardFigur : eigeneFigur; + synchronized (figur) + { + for (FigurenElement e: figur) + { + e.ElementZeichnen(g2, größe, x, y); + } + } + } + g2.setTransform(alt); + } + } +} diff --git a/package.bluej b/package.bluej new file mode 100644 index 0000000..da3ab8a --- /dev/null +++ b/package.bluej @@ -0,0 +1,170 @@ +#BlueJ package file +dependency1.from=Turtle +dependency1.to=Zeichenfenster +dependency1.type=UsesDependency +dependency10.from=Aufbau +dependency10.to=DreieckBesser +dependency10.type=UsesDependency +dependency11.from=Aufbau +dependency11.to=RechteckBesser +dependency11.type=UsesDependency +dependency12.from=Ereignisbehandlung +dependency12.to=Zeichenfenster +dependency12.type=UsesDependency +dependency13.from=Zeichenfenster +dependency13.to=Rechteck +dependency13.type=UsesDependency +dependency14.from=Zeichenfenster +dependency14.to=Dreieck +dependency14.type=UsesDependency +dependency15.from=Zeichenfenster +dependency15.to=Kreis +dependency15.type=UsesDependency +dependency16.from=Zeichenfenster +dependency16.to=Turtle +dependency16.type=UsesDependency +dependency17.from=Zeichenfenster +dependency17.to=Figur +dependency17.type=UsesDependency +dependency18.from=Kreis +dependency18.to=Zeichenfenster +dependency18.type=UsesDependency +dependency2.from=Rechteck +dependency2.to=Zeichenfenster +dependency2.type=UsesDependency +dependency3.from=Aufbau2 +dependency3.to=RechteckBesser +dependency3.type=UsesDependency +dependency4.from=Aufbau2 +dependency4.to=DreieckBesser +dependency4.type=UsesDependency +dependency5.from=Aufbau2 +dependency5.to=KreisBesser +dependency5.type=UsesDependency +dependency6.from=Figur +dependency6.to=Zeichenfenster +dependency6.type=UsesDependency +dependency7.from=Text +dependency7.to=Zeichenfenster +dependency7.type=UsesDependency +dependency8.from=Dreieck +dependency8.to=Zeichenfenster +dependency8.type=UsesDependency +dependency9.from=Aufbau +dependency9.to=KreisBesser +dependency9.type=UsesDependency +editor.fx.0.height=0 +editor.fx.0.width=0 +editor.fx.0.x=0 +editor.fx.0.y=0 +objectbench.height=174 +objectbench.width=1256 +package.divider.horizontal=0.5998578535891969 +package.divider.vertical=0.6901248581157774 +package.editor.height=397 +package.editor.width=1132 +package.editor.x=0 +package.editor.y=0 +package.frame.height=686 +package.frame.width=1294 +package.numDependencies=18 +package.numTargets=13 +package.showExtends=true +package.showUses=true +project.charset=UTF-8 +readme.height=60 +readme.name=@README +readme.width=48 +readme.x=10 +readme.y=10 +target1.height=50 +target1.name=Turtle +target1.showInterface=false +target1.type=ClassTarget +target1.width=80 +target1.x=510 +target1.y=100 +target10.height=50 +target10.name=KreisBesser +target10.showInterface=false +target10.type=ClassTarget +target10.width=90 +target10.x=430 +target10.y=210 +target11.height=50 +target11.name=Zeichenfenster +target11.showInterface=false +target11.type=ClassTarget +target11.width=120 +target11.x=70 +target11.y=20 +target12.height=50 +target12.name=DreieckBesser +target12.showInterface=false +target12.type=ClassTarget +target12.width=110 +target12.x=290 +target12.y=240 +target13.height=50 +target13.name=Kreis +target13.showInterface=false +target13.type=ClassTarget +target13.width=80 +target13.x=400 +target13.y=120 +target2.height=50 +target2.name=Rechteck +target2.showInterface=false +target2.type=ClassTarget +target2.width=80 +target2.x=190 +target2.y=160 +target3.height=50 +target3.name=Aufbau2 +target3.showInterface=false +target3.type=ClassTarget +target3.width=80 +target3.x=780 +target3.y=310 +target4.height=50 +target4.name=Figur +target4.showInterface=false +target4.type=ClassTarget +target4.width=80 +target4.x=620 +target4.y=80 +target5.height=50 +target5.name=Text +target5.showInterface=false +target5.type=ClassTarget +target5.width=80 +target5.x=720 +target5.y=60 +target6.height=50 +target6.name=Dreieck +target6.showInterface=false +target6.type=ClassTarget +target6.width=80 +target6.x=290 +target6.y=140 +target7.height=50 +target7.name=Aufbau +target7.showInterface=false +target7.type=ClassTarget +target7.width=80 +target7.x=610 +target7.y=330 +target8.height=50 +target8.name=RechteckBesser +target8.showInterface=false +target8.type=ClassTarget +target8.width=120 +target8.x=140 +target8.y=270 +target9.height=50 +target9.name=Ereignisbehandlung +target9.showInterface=false +target9.type=ClassTarget +target9.width=150 +target9.x=820 +target9.y=40