import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
/**
* Class ZEICHENFENSTER - Eine Klasse, die einfache grafische Zeichnungen
* in einem Programmfenster ermöglicht.
*
* @author Michael Kolling (mik)
* @author Bruce Quig
* @author Christian Heidrich
*
* @version 2007.05.07
*/
public class ZEICHENFENSTER
{
private JFrame frame;
private CanvasPane canvas;
private JPanel steuerungOst,steuerungSued;
private Graphics2D graphic;
private Color backgroundColor;
private Image canvasImage;
private static ZEICHENFENSTER singleton;
/**
* Erzeugt eine Zeichenfenster mit Standardmaßen 600*500 und Hintergrundfarbe weiß
* @param titel Titel des Fensters
*/
public ZEICHENFENSTER(String titel)
{
this(titel, 500, 250, Color.white);
}
/**
* Erzeugt ein Zeichenfenster mit weißem Hintergrund.
* @param titel Fensterueberschirft
* @param breite Breite des Fensters
* @param hoehe Hoehe des Fensters
*/
public ZEICHENFENSTER(String titel, int breite, int hoehe)
{
this(titel, breite, hoehe, Color.white);
}
/**
* Erzeugt ein Zeichenfenster.
* @param titel Fensterueberschirft
* @param breite Breite des Fensters
* @param hoehe Hoehe des Fensters
* @param hintergrundFarbe Hintergrundfarbe des Zeichenfensters
*/
private ZEICHENFENSTER(String titel, int breite, int hoehe, Color hintergrundFarbe)
{
frame = new JFrame();
canvas = new CanvasPane();
canvas.setPreferredSize(new Dimension(breite, hoehe));
frame.getContentPane().add(canvas,BorderLayout.CENTER);
JPanel p1=new JPanel();
p1.setLayout(new BorderLayout());
steuerungOst = new JPanel();
steuerungSued = new JPanel();
//frame.addMouseListener(new Senet());
steuerungOst.setLayout(new BoxLayout(steuerungOst,BoxLayout.Y_AXIS));
steuerungSued.setLayout(new BoxLayout(steuerungSued,BoxLayout.X_AXIS));
p1.add(steuerungOst,BorderLayout.NORTH);
frame.getContentPane().add(p1,BorderLayout.EAST);
frame.getContentPane().add(steuerungSued,BorderLayout.SOUTH);
frame.setTitle(titel);
backgroundColor = hintergrundFarbe;
frame.pack();
zeige();
}
public static ZEICHENFENSTER gibFenster()
{
if (singleton==null){singleton=new ZEICHENFENSTER("Pong - By Sebastian Goehring", 600, 300, Color.black);}// 836, 704,
singleton.zeige();
return singleton;
}
/**
* Macht das Zeichenfenster sichtbar bzw. setzt es in den Vordergrund,
* falls es bereits sichtbar ist.
*/
public void zeige()
{
if(graphic == null) {
// nur beim ersten Aufruf wird der Hintergrund mit der Hintergrundfarbe
// gefuellt
Dimension size = canvas.getSize();
canvasImage = canvas.createImage(size.width, size.height);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.setColor(backgroundColor);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
frame.setVisible(true);
}
/**
* Gibt Information über die Sichtbarkeit.
* @return true falls das Fenster sichtbar ist.
*/
public boolean istSichtbar()
{
return frame.isVisible();
}
/**
* Zeichnet einen Elipsenbogen (Siehe Graphics.drawArc)
* @param x x-Koordinate des Elipsenmittelpunkts
* @param y y-Koordinate des Elipsenmittelpunkts
* @param halbachseX Halbachse der Elipse in x-Richtung
* @param halbachseY Halbachse der Elipse in y-Richtung
* @param startWinkel Polarwinkel, an dem der Bogen anfängt
* @param winkel Polarwinkel, welchen der Bogen durchläuft
*/
public void zeichneBogen(int x, int y, int halbachseX, int halbachseY, int startWinkel, int winkel)
{
graphic.drawArc(x-halbachseX,y-halbachseY,2*halbachseX,2*halbachseY,startWinkel,winkel);
canvas.repaint();
}
/**
* Zeichnet einen Kreis (Siehe Graphics.drawOval)
* @param x x-Koordinate des Mittelpunkts
* @param y y-Koordinate des Mittelpunkts
* @param radius Kreisradius
*/
public void zeichneKreis(int x, int y, int radius)
{
graphic.drawOval(x-radius,y-radius,2*radius,2*radius);
canvas.repaint();
}
/**
* Füllt das Innere eines Kreises mit der angegebenen Farbe.
* @param x x-Koordinate des Mittelpunkts
* @param y y-Koordinate des Mittelpunkts
* @param radius Kreisradius
* @param farbe Füllfarbe für den Kreis, erlaubt sind "weiss" "schwarz" "rot"
* "gruen" "blau" "gelb" "magenta" "cyan" "grau"
*/
public void fuelleKreis(int x, int y, int radius, String farbe)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbe));
graphic.fillOval(x-radius,y-radius,2*radius,2*radius);
canvas.repaint();
graphic.setColor(original);
}
/**
* Füllt das Innere eines Kreises mit der angegebenen Farbe.
* @param x x-Koordinate des Mittelpunkts
* @param y y-Koordinate des Mittelpunkts
* @param radius Kreisradius
* @param farbnr Füllfarbnummer für den Kreis (0 bis 8)
*/
public void fuelleKreis(int x, int y, int radius, int farbnr)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbnr));
graphic.fillOval(x-radius,y-radius,2*radius,2*radius);
canvas.repaint();
graphic.setColor(original);
}
/**
* Löscht das Innere eines Kreises
* @param x x-Koordinate des Mittelpunkts
* @param y y-Koordinate des Mittelpunkts
* @param radius Kreisradius
*/
public void loescheKreis(int x, int y, int radius)
{
Ellipse2D.Double circle = new Ellipse2D.Double(x-radius, y-radius, 2*radius, 2*radius);
loesche(circle);
}
/**
* Zeichnet den Umriss eines Shape-Objekts.
* @param shape das Shape-Object, welches gezeichnet werden soll
*/
public void zeichne(Shape shape)
{
graphic.draw(shape);
canvas.repaint();
}
/**
* Füllt das Innere eines Shape-Objekts mit der angegebenen Farbe.
* @param shape das Shape-Objekt, welches gefüllt werden soll
* @param farbe Füllfarbe für das Shape-Objekt, erlaubt sind "weiss" "schwarz" "rot"
* "gruen" "blau" "gelb" "magenta" "cyan" "grau"
*/
public void fuelle(Shape shape, String farbe)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbe));
graphic.fill(shape);
canvas.repaint();
graphic.setColor(original);
}
/**
* Füllt das Innere eines Shape-Objekts mit der angegebenen Farbe.
* @param shape das Shape-Objekt, welches gefüllt werden soll
* @param farbnr Füllfarbnummer für das Shape-Objekt (0 bis 8)
*/
public void fuelle(Shape shape, int farbnr)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbnr));
graphic.fill(shape);
canvas.repaint();
graphic.setColor(original);
}
/**
* Löscht das Innere eines Shape-Objekts.
* @param shape das Shape-Object, welches gelöscht werden soll
*/
public void loesche(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.fill(shape); // erase by filling background color
graphic.setColor(original);
canvas.repaint();
}
/**
* Zeichnet den Rand des Rechtecks mit der aktuellen Farbe.
* @param xPos,yPos Koordinaten der linken oberen Ecke
* @param breite, hoehe Breite und Höhe des Rechtecks
*/
public void zeichneRechteck(int xPos, int yPos, int breite, int hoehe)
{
graphic.drawRect(xPos, yPos, breite, hoehe);
canvas.repaint();
// fill(new Rectangle(xPos, yPos, breite, hoehe));
}
/**
* Füllt das Innere des Rechtecks mit der angegebenen Farbe.
* @param xPos,yPos Koordinaten der linken oberen Ecke
* @param breite, hoehe Breite und Höhe des Rechtecks
* @param farbe Füllfarbe für das Rechteck, erlaubt sind "weiss" "schwarz" "rot"
* "gruen" "blau" "gelb" "magenta" "cyan" "grau"
*/
public void fuelleRechteck(int xPos, int yPos, int breite, int hoehe, String farbe)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbe));
graphic.fillRect(xPos, yPos, breite, hoehe);
canvas.repaint();
graphic.setColor(original);
}
/**
* Füllt das Innere des Rechtecks mit der angegebenen Farbe.
* @param xPos,yPos Koordinaten der linken oberen Ecke
* @param breite, hoehe Breite und Höhe des Rechtecks
* @param farbnr Füllfarbnummer für das Rechteck (0 bis 8)
*/
public void fuelleRechteck(int xPos, int yPos, int breite, int hoehe, int farbnr)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbnr));
graphic.fillRect(xPos, yPos, breite, hoehe);
canvas.repaint();
graphic.setColor(original);
}
/**
* Löscht das Innere eines Rechtecks.
* @param xPos,yPos Koordinaten der linken oberen Ecke
* @param breite, hoehe Breite und Höhe des Rechtecks
*/
public void loescheRechteck(int xPos, int yPos, int breite, int hoehe)
{
loesche(new Rectangle(xPos, yPos, breite, hoehe));
}
private Polygon gibDreieck(int x1, int y1, int x2, int y2, int x3, int y3)
{
Polygon p=new Polygon();
p.addPoint(x1,y1);
p.addPoint(x2,y3);
p.addPoint(x3,y3);
return p;
}
/**
* Zeichnet den Rand eines Dreiecks mit der aktuellen Farbe.
* @param x1,y1 Koordinaten des ersten Eckpunkts
* @param x2,y2 Koordinaten des zweiten Eckpunkts
* @param x3,y3 Koordinaten des dritten Eckpunkts
*/
public void zeichneDreieck(int x1, int y1, int x2, int y2, int x3, int y3)
{
graphic.drawPolygon(gibDreieck(x1, y1, x2, y2, x3, y3));
canvas.repaint();
}
/**
* Füllt das Innere eines Dreiecks mit der angegebenen Farbe.
* @param x1,y1 Koordinaten des ersten Eckpunkts
* @param x2,y2 Koordinaten des zweiten Eckpunkts
* @param x3,y3 Koordinaten des dritten Eckpunkts
* @param farbe Füllfarbe für das Dreieck, erlaubt sind "weiss" "schwarz" "rot"
* "gruen" "blau" "gelb" "magenta" "cyan" "grau"
*/
public void fuelleDreieck(int x1, int y1, int x2, int y2, int x3, int y3, String farbe)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbe));
graphic.fillPolygon(gibDreieck(x1, y1, x2, y2, x3, y3));
canvas.repaint();
graphic.setColor(original);
}
/**
* Füllt das Innere eines Dreiecks mit der angegebenen Farbe.
* @param x1,y1 Koordinaten des ersten Eckpunkts
* @param x2,y2 Koordinaten des zweiten Eckpunkts
* @param x3,y3 Koordinaten des dritten Eckpunkts
* @param farbnr Füllfarbnummer für das Dreieck (0 bis 8)
*/
public void fuelleDreieck(int x1, int y1, int x2, int y2, int x3, int y3, int farbnr)
{
Color original=graphic.getColor();
graphic.setColor(farbeZuColor(farbnr));
graphic.fillPolygon(gibDreieck(x1, y1, x2, y2, x3, y3));
canvas.repaint();
graphic.setColor(original);
}
/**
* Löscht das Innere eines Dreicks
* @param x1,y1 Koordinaten des ersten Eckpunkts
* @param x2,y2 Koordinaten des zweiten Eckpunkts
* @param x3,y3 Koordinaten des dritten Eckpunkts
*/
public void loescheDreieck(int x1, int y1, int x2, int y2, int x3, int y3)
{
loesche(gibDreieck(x1, y1, x2, y2, x3, y3));
}
/**
* Löscht den Inhalt des Zeichenfensters.
*/
public void loescheAlles()
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
Dimension size = canvas.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
canvas.repaint();
}
/**
* Löscht den Umriss eines Shape-Objekts.
* @param shape das Shape-Object, dessen Umriss gelöscht werden soll
*/
public void loescheRand(Shape shape)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.draw(shape); // Löschen durch übermalen mit Hintergrundfarbe
graphic.setColor(original);
canvas.repaint();
}
/**
* Zeichnet ein Bild in das Zeichnenfenster .
* @param bild das anzuzeigende Bild
* @param x x-Koordinate des linken Bildrands
* @param y y-Koordinate des oberen Bildrands
* @return gibt eines booleschen Wert zurück, der angibt, ob das Bild vollständig geladen
* werden konnte
*/
public boolean zeichneBild(Image bild, int x, int y)
{
boolean result = graphic.drawImage(bild, x, y, null);
canvas.repaint();
return result;
}
/**
* Zeichnet einen Text.
* @param text die anzuzeigende Zeichenkette
* @param x x-Koordinate des linken Rands
* @param y y-Koordinate des oberen Rands
*/
public void zeichneText(String text, int x, int y)
{
graphic.drawString(text, x, y);
canvas.repaint();
}
/**
* Löscht einen Text vom Zeichenfenster.
* @param text die zu löschende Zeichenkette
* @param x x-Koordinate des linken Rands
* @param y y-Koordinate des oberen Rands
*/
public void loescheText(String text, int x, int y)
{
Color original = graphic.getColor();
graphic.setColor(backgroundColor);
graphic.drawString(text, x, y);
graphic.setColor(original);
canvas.repaint();
}
/**
* Zeichnet eine Strecke ins Zeichenfenster.
* @param x1 x-Koordinate des Anfangspunkts der Strecke
* @param y1 y-Koordinate des Anfangspunkts der Strecke
* @param x2 x-Koordinate des Endpunkts der Strecke
* @param y2 y-Koordinate des Endpunkts der Strecke
*/
public void zeichneStrecke(int x1, int y1, int x2, int y2)
{
graphic.drawLine(x1, y1, x2, y2);
canvas.repaint();
}
/**
* Setzt die Vordergrundfarbe des Zeichenfensters.
* @param neueFarbe neue Vordergrundfarbe
*/
public void setzeVordergrundFarbe(String neueFarbe)
{
graphic.setColor(farbeZuColor(neueFarbe));
}
private void setzeVordergrundFarbe(Color neueFarbe)
{
graphic.setColor(neueFarbe);
}
private Color farbeZuColor(int farbnr)
{
switch (farbnr)
{
case 0: return Color.black;
case 1: return Color.blue;
case 2: return Color.green;
case 3: return Color.cyan;
case 4: return Color.red;
case 5: return Color.magenta;
case 6: return Color.yellow;
case 7: return Color.gray;
case 8: return Color.white;
default: return graphic.getColor();
}
}
private Color farbeZuColor(String farbe)
{
if (farbe=="weiss") return Color.white;
if (farbe=="schwarz") return Color.black;
if (farbe=="rot") return Color.red;
if (farbe=="gruen") return Color.green;
if (farbe=="blau") return Color.blue;
if (farbe=="gelb") return Color.yellow;
if (farbe=="magenta") return Color.magenta;
if (farbe=="cyan") return Color.cyan;
if (farbe=="grau") return Color.gray;
return graphic.getColor();
}
private String colorZuFarbe(Color color)
{
if (color==Color.white) return "weiss";
if (color==Color.black) return "schwarz";
if (color==Color.red) return "rot";
if (color==Color.green) return "gruen";
if (color==Color.blue) return "blau";
if (color==Color.yellow) return "gelb";
if (color==Color.magenta) return "magenta";
if (color==Color.cyan) return "cyan";
if (color==Color.gray) return "gruen";
return "";
}
/**
* Gibt die aktuelle Vordergrundfarbe des Zeichenfensters zurück.
* @return die aktuelle Vordergrundfarbe
*/
public String gibVordergrundFarbe()
{
return colorZuFarbe(graphic.getColor());
}
//public Color gibVordergrundFarbe()
//{
// return graphic.getColor();
//}
/**
* Setzt die Hintergrundfarbe des Zeichenfensters.
* @param neueFarbe neue Hintergrundfarbe
*/
public void setzeHintergrundFarbe(String neueFarbe)
{
backgroundColor = farbeZuColor(neueFarbe);
graphic.setBackground(backgroundColor);
}
private void setzeHintergrundFarbe(Color neueFarbe)
{
backgroundColor = neueFarbe;
graphic.setBackground(neueFarbe);
}
/**
* Gibt die aktuelle Hintergrundfarbe des Zeichenfensters zurück.
* @return die aktuelle Hintergrundfarbe
*/
public String gibHintergrundFarbe()
{
return colorZuFarbe(backgroundColor);
}
//public Color gibHintergrundFarbe()
//{
// return backgroundColor;
//}
/**
* Ändert den aktuellen Zeichensatz des Zeichenfensters.
* @param neuerZeichensatz Zeichensatz, der künftig für Zeichenkettenausgaben verwendet wird
*/
public void setzeZeichensatz(Font neuerZeichensatz)
{
graphic.setFont(neuerZeichensatz);
}
/**
* Gibt den aktuellen Zeichensatz des Zeichenfensters zurück.
* @return den aktuellen Zeichensatz
**/
public Font gibZeichensatz()
{
return graphic.getFont();
}
/**
* Ändert die Abmessungen des Zeichenfensters.
* @param breite neue Breite
* @param hoehe neue Höhe
*/
public void setzeMasse(int breite, int hoehe)
{
canvas.setPreferredSize(new Dimension(breite, hoehe));
Image oldImage = canvasImage;
canvasImage = canvas.createImage(breite, hoehe);
graphic = (Graphics2D)canvasImage.getGraphics();
graphic.drawImage(oldImage, 0, 0, null);
frame.pack();
}
/**
* Gibt die Abmessungen des Zeichenfensters zurück.
* @return die aktuellen Abmessungen des Zeichenfensters
*/
public Dimension gibMasse()
{
return canvas.getSize();
}
/**
* Wartet eine bestimmte Zeit.
* Eine kurze Verzögerung kann z. B. für Animationen verwendet werden.
* @param zeit Wartezeit in Millisekunden
*/
public void warte(int zeit)
{
try
{
Thread.sleep(zeit);
}
catch (InterruptedException e)
{
// ignoring exception at the moment
}
}
/**
* Fügt ein weiteres Steuerungselement in die rechte Steuerungsleiste ein.
* @param element Das einzufügende Steuerungselement muss aus JComponent abgeleitet
* sein. z. B. JButton, JComboBox.
*/
public void komponenteHinzufuegen(JComponent element, String position)
{
if (position=="rechts") steuerungOst.add(element);
else if (position=="unten") steuerungSued.add(element);
frame.pack();
}
/**
* Beschriftet den Titel des Zeichenfensters neu.
* @param titelNeu Text der neuen Fensterüberschrift
*/
public void setzeTitel(String titelNeu)
{
frame.setTitle(titelNeu);
}
/************************************************************************
* Nested class CanvasPane - the actual canvas component contained in the
* Canvas frame. This is essentially a JPanel with added capability to
* refresh the image drawn on it.
*/
private class CanvasPane extends JPanel
{
private static final long serialVersionUID = 20060330L;
public void paint(Graphics g)
{
g.drawImage(canvasImage, 0, 0, null);
}
}
/* neue Funktion, um von außen einen Mausadapter für den Zeichenbereich hinzufügen zu können */
public static void AddMouseAdapter(MouseMotionAdapter mouseMotionAdapter)
{
singleton.canvas.addMouseMotionListener(mouseMotionAdapter);
}
/* neue Funktion, um von außen einen Keyadapter für den Zeichenbereich hinzufügen zu können */
public static void AddKeyAdapter(KeyAdapter keyAdapter)
{
singleton.canvas.addKeyListener(keyAdapter);
}
}