// Thread zur Zeichnung und Animation von Kreis1
public class Aufgabe4 implements Runnable
{
private Kreis k1;
public Aufgabe4()
{
k1 = new Kreis();
}
public void zeichnen1()
{
k1.setzeDurchmesser(50);
k1.setzePosition(25,100);
k1.sichtbarMachen();
}
public void animation1()
{
k1.langsamHorizontalBewegen(-25);
}
public void run()
{
zeichnen1();
animation1();
}
}
// Thread zur Zeichnung und Animation von Kreis2
public class Aufgabe41 implements Runnable
{
private Kreis k2;
public Aufgabe41()
{
k2 = new Kreis();
}
public void zeichnen2()
{
k2.setzeDurchmesser(50);
k2.setzePosition(75,100);
k2.sichtbarMachen();
}
public void animation2()
{
k2.langsamHorizontalBewegen(25);
}
public void run()
{
zeichnen2();
animation2();
}
}
//Thread zur Zeichnung vom Quadrat
public class Aufgabe42 implements Runnable
{
private Quadrat q1;
public Aufgabe42()
{
q1 = new Quadrat();
}
public void zeichnen3()
{
q1.setzeSeitenlaenge(50);
q1.setzePosition(50,100);
q1.sichtbarMachen();
}
public void run()
{
zeichnen3();
}
}
// Thread zur Gesamtlösung
public class Loesung1 implements Runnable
{
public void run()
{
Thread a = new Thread(new Aufgabe4());
Thread b = new Thread(new Aufgabe41());
Thread c = new Thread(new Aufgabe42());
a.start();
b.start();
c.start();
}
public static void main(String[] args)
{
Thread z = new Thread(new Loesung1());
z.start();
}
}
import java.awt.Rectangle;
/**
* Ein Quadrat, das manipuliert werden kann und sich selbst auf einer Leinwand
* zeichnet.
*
* @author Michael Kölling und David J. Barnes
* @version 2006.03.30.
* Für die IBBB-Tagung 2007 leicht modifiziert von Alexander Dietz (04.03.2007)
*/
public class Quadrat {
private int laenge;
private int xPosition;
private int yPosition;
private String farbe;
private boolean istSichtbar;
/**
* Erzeuge ein neues Quadrat mit einer Standardfarbe an einer
* Standardposition.
*/
public Quadrat() {
laenge = 30;
xPosition = 60;
yPosition = 50;
farbe = "rot";
istSichtbar = false;
}
/**
* Erzeuge ein neues Quadrat. Die Startwerte können eingegeben werden.
* @param x die x-Koordinate des linken oberen Eckpunktes
* @param y die y-Koordinate des linken oberen Eckpunktes
* @param l die Seitenlaenge des Quadrates
* @param f die Farbe des Quadrates ("rot", "gelb", "blau", "gruen", "lila", "schwarz")
*/
public Quadrat(int x, int y, int l, String f) {
xPosition = x;
yPosition = y;
laenge = l;
farbe = f;
istSichtbar = false;
}
/**
* Ändere die Seitenlaenge dieses Quadrates in 'l'.
* @param l die neue Seitenlaenge des Quadrates (groesser gleich 0)
*/
public void setzeSeitenlaenge(int l)
{
loeschen();
if (l>=0)
laenge = l;
else
System.out.println("Diese Eingabe ist nicht plausibel.");
zeichnen();
}
/**
* Ändere die Position des Quadrates.
* @param x die x-Koordinate des linken oberen Eckpunktes
* @param y die y-Koordinate des linken oberen Eckpunktes
*/
public void setzePosition(int x, int y) {
loeschen();
if ((x>=0) && (y>=0)) {
xPosition=x;
yPosition=y;
}
else
System.out.println("Diese Eingabe ist nicht plausibel.");
zeichnen();
}
/**
* Mache dieses Quadrat sichtbar. Wenn es bereits sichtbar ist, tue nichts.
*/
public void sichtbarMachen() {
istSichtbar = true;
zeichnen();
}
/**
* Mache dieses Quadrat unsichtbar. Wenn es bereits unsichtbar ist, tue
* nichts.
*/
public void unsichtbarMachen() {
loeschen();
istSichtbar = false;
}
/**
* Bewege dieses Quadrat einige Bildschirmpunkte nach rechts.
*/
public void nachRechtsBewegen() {
horizontalBewegen(20);
}
/**
* Bewege dieses Quadrat einige Bildschirmpunkte nach links.
*/
public void nachLinksBewegen() {
horizontalBewegen(-20);
}
/**
* Bewege dieses Quadrat einige Bildschirmpunkte nach oben.
*/
public void nachObenBewegen() {
vertikalBewegen(-20);
}
/**
* Bewege dieses Quadrat einige Bildschirmpunkte nach unten.
*/
public void nachUntenBewegen() {
vertikalBewegen(20);
}
/**
* Bewege dieses Quadrat horizontal um 'entfernung' Bildschirmpunkte.
* @param entfernung
*/
public void horizontalBewegen(int entfernung) {
loeschen();
xPosition += entfernung;
zeichnen();
}
/**
* Bewege dieses Quadrat vertikal um 'entfernung' Bildschirmpunkte.
*/
public void vertikalBewegen(int entfernung) {
loeschen();
yPosition += entfernung;
zeichnen();
}
/**
* Bewege dieses Quadrat langsam horizontal um 'entfernung'
* Bildschirmpunkte.
*/
public void langsamHorizontalBewegen(int entfernung) {
int delta;
if (entfernung < 0) {
delta = -1;
entfernung = -entfernung;
} else {
delta = 1;
}
for (int i = 0; i < entfernung; i++) {
xPosition += delta;
zeichnen();
}
}
/**
* Bewege dieses Quadrat langsam vertikal um 'entfernung' Bildschirmpunkte.
*/
public void langsamVertikalBewegen(int entfernung) {
int delta;
if (entfernung < 0) {
delta = -1;
entfernung = -entfernung;
} else {
delta = 1;
}
for (int i = 0; i < entfernung; i++) {
yPosition += delta;
zeichnen();
}
}
/**
* Ändere die Farbe dieses Quadrates in 'neueFarbe'. Gültige Angaben sind
* "rot", "gelb", "blau", "gruen", "lila" und "schwarz".
*/
public void farbeAendern(String neueFarbe) {
farbe = neueFarbe;
zeichnen();
}
/**
* Zeichne dieses Quadrat mit seinen aktuellen Werten auf den Bildschirm.
*/
private void zeichnen() {
if (istSichtbar) {
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.zeichne(this, farbe, new Rectangle(xPosition, yPosition,
laenge, laenge));
leinwand.warte(10);
}
}
/**
* Lösche dieses Quadrat vom Bildschirm.
*/
private void loeschen() {
if (istSichtbar) {
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.entferne(this);
}
}
}
import java.awt.geom.Ellipse2D;
/**
* Ein Kreis, der manipuliert werden kann und sich selbst auf einer Leinwand
* zeichnet.
*
* @author Michael Kölling und David J. Barnes
* @version 2006.03.30.
* Für die IBBB-Tagung 2007 leicht modifiziert von Alexander Dietz (04.03.2007)
*/
public class Kreis {
private int durchmesser;
private int xPosition;
private int yPosition;
private String farbe;
private boolean istSichtbar;
/**
* Erzeuge einen neuen Kreis an einer Standardposition mit einer
* Standardfarbe.
*/
public Kreis() {
durchmesser = 30;
xPosition = 20;
yPosition = 60;
farbe = "blau";
istSichtbar = false;
}
/**
* Erzeuge einen neuen Kreis. Die Startwerte können eingegeben werden.
* @param x die x-Koordinate des Kreismittelpunktes
* @param y die y-Koordinate des Kreismittelpunktes
* @param d der Durchmesser des Kreises
* @param f die Farbe des Rechteckes ("rot", "gelb", "blau", "gruen", "lila", "schwarz")
*/
public Kreis(int x, int y, int d, String f) {
xPosition = x;
yPosition = y;
durchmesser = d;
farbe = f;
istSichtbar = false;
}
/**
* Mache diesen Kreis sichtbar. Wenn es bereits sichtbar ist, tue nichts.
*/
public void sichtbarMachen() {
istSichtbar = true;
zeichnen();
}
/**
* Mache diesen Kreis unsichtbar. Wenn es bereits unsichtbar ist, mache
* nichts.
*/
public void unsichtbarMachen() {
loeschen();
istSichtbar = false;
}
/**
* Bewege diesen Kreis einige Bildschirmpunkte nach rechts.
*/
public void nachRechtsBewegen() {
horizontalBewegen(20);
}
/**
* Bewege diesen Kreis einige Bildschirmpunkte nach links.
*/
public void nachLinksBewegen() {
horizontalBewegen(-20);
}
/**
* Bewege diesen Kreis einige Bildschirmpunkte nach oben.
*/
public void nachObenBewegen() {
vertikalBewegen(-20);
}
/**
* Bewege diesen Kreis einige Bildschirmpunkte nach unten.
*/
public void nachUntenBewegen() {
vertikalBewegen(20);
}
/**
* Bewege diesen Kreis horizontal um 'entfernung' Bildschirmpunkte.
* @param entfernung
*/
public void horizontalBewegen(int entfernung) {
loeschen();
xPosition += entfernung;
zeichnen();
}
/**
* Bewege diesen Kreis vertikal um 'entfernung' Bildschirmpunkte.
* @param entfernung
*/
public void vertikalBewegen(int entfernung) {
loeschen();
yPosition += entfernung;
zeichnen();
}
/**
* Bewege diesen Kreis langsam horizontal um 'entfernung' Bildschirmpunkte.
* @param entfernung
*/
public void langsamHorizontalBewegen(int entfernung) {
int delta;
if (entfernung < 0) {
delta = -1;
entfernung = -entfernung;
} else {
delta = 1;
}
for (int i = 0; i < entfernung; i++) {
xPosition += delta;
zeichnen();
}
}
/**
* Bewege diesen Kreis langsam vertikal um 'entfernung' Bildschirmpunkte.
* @param entfernung
*/
public void langsamVertikalBewegen(int entfernung) {
int delta;
if (entfernung < 0) {
delta = -1;
entfernung = -entfernung;
} else {
delta = 1;
}
for (int i = 0; i < entfernung; i++) {
yPosition += delta;
zeichnen();
}
}
/**
* Ändere den Durchmesser dieses Kreises in 'neuerDurchmesser' (Angabe in
* Bildschirmpunkten). 'neuerDurchmesser' muss größer gleich Null sein.
* @param neuerDurchmesser der neue Durchmesser
*/
public void setzeDurchmesser(int neuerDurchmesser) {
loeschen();
if (durchmesser>=0)
durchmesser = neuerDurchmesser;
else
System.out.println("Diese Eingabe ist nicht plausibel.");
zeichnen();
}
/**
* Ändere die Position des Kreises
* 'neuesX' und 'neuesY' müssen größer gleich Null sein.
* @param neuesX die neue x-Koordinate des Kreismittelpunktes
* @param neuesY die neue y-Koordinate des Kreismittelpunktes
*/
public void setzePosition(int neuesX, int neuesY) {
loeschen();
if ((neuesX>=0) && (neuesY>=0)) {
xPosition=neuesX;
yPosition=neuesY;
}
else
System.out.println("Diese Eingabe ist nicht plausibel.");
zeichnen();
}
/**
* Ändere die Farbe dieses Kreises in 'neueFarbe'. Gültige Angaben sind
* "rot", "gelb", "blau", "gruen", "lila" und "schwarz".
* @param neueFarbe
*/
public void farbeAendern(String neueFarbe) {
farbe = neueFarbe;
zeichnen();
}
/**
* Zeichne diesen Kreis mit seinen aktuellen Werten auf den Bildschirm.
*/
private void zeichnen() {
if (istSichtbar) {
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.zeichne(this, farbe, new Ellipse2D.Double(xPosition,
yPosition, durchmesser, durchmesser));
leinwand.warte(10);
}
}
/**
* Lösche diesen Kreis vom Bildschirm.
*/
private void loeschen() {
if (istSichtbar) {
Leinwand leinwand = Leinwand.gibLeinwand();
leinwand.entferne(this);
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* Leinwand ist eine Klasse, die einfache Zeichenoperationen auf einer
* leinwandartigen Zeichenfläche ermöglicht. Sie ist eine vereinfachte Version
* der Klasse Canvas (englisch für Leinwand) des JDK und wurde speziell für das
* Projekt "Figuren" geschrieben.
*
*
* @author: Bruce Quig
* @author: Michael Kölling (mik)
* @author: Axel Schmolitzky
*
*
*/
public class Leinwand {
// Hinweis: Die Implementierung dieser Klasse (insbesondere die
// Verwaltung der Farben und Identitäten der Figuren) ist etwas
// komplizierter als notwendig. Dies ist absichtlich so, weil damit
// die Schnittstellen und Exemplarvariablen der Figuren-Klassen
// für den Lernanspruch dieses Projekts einfacher und klarer
// sein können.
private static Leinwand leinwandSingleton;
/**
* Fabrikmethode, die eine Referenz auf das einzige Exemplar dieser Klasse
* zurückliefert. Wenn es von einer Klasse nur genau ein Exemplar gibt, wird
* dieses als 'Singleton' bezeichnet.
*/
public static Leinwand gibLeinwand() {
if (leinwandSingleton == null) {
leinwandSingleton = new Leinwand("BlueJ Figuren Demo", 300, 300,
Color.white);
}
leinwandSingleton.setzeSichtbarkeit(true);
return leinwandSingleton;
}
// ----- Exemplarvariablen -----
private JFrame fenster;
private Zeichenflaeche zeichenflaeche;
private Graphics2D graphic;
private Color hintergrundfarbe;
private Image leinwandImage;
private List<Object> figuren;
private Map<Object, ShapeMitFarbe> figurZuShape;
/**
* Erzeuge eine Leinwand.
*
* @param titel
* Titel, der im Rahmen der Leinwand angezeigt wird
* @param breite
* die gewünschte Breite der Leinwand
* @param hoehe
* die gewünschte Höhe der Leinwand
* @param grundfarbe
* die Hintergrundfarbe der Leinwand
*/
private Leinwand(String titel, int breite, int hoehe, Color grundfarbe) {
fenster = new JFrame();
zeichenflaeche = new Zeichenflaeche();
fenster.setContentPane(zeichenflaeche);
fenster.setTitle(titel);
zeichenflaeche.setPreferredSize(new Dimension(breite, hoehe));
hintergrundfarbe = grundfarbe;
fenster.pack();
figuren = new ArrayList<Object>();
figurZuShape = new HashMap<Object, ShapeMitFarbe>();
}
/**
* Setze, ob diese Leinwand sichtbar sein soll oder nicht. Wenn die Leinwand
* sichtbar gemacht wird, wird ihr Fenster in den Vordergrund geholt. Diese
* Operation kann auch benutzt werden, um ein bereits sichtbares
* Leinwandfenster in den Vordergrund (vor andere Fenster) zu holen.
*
* @param sichtbar
* boolean für die gewünschte Sichtbarkeit: true für sichtbar,
* false für nicht sichtbar.
*/
public void setzeSichtbarkeit(boolean sichtbar) {
if (graphic == null) {
// erstmaliger Aufruf: erzeuge das Bildschirm-Image und fülle
// es mit der Hintergrundfarbe
Dimension size = zeichenflaeche.getSize();
leinwandImage = zeichenflaeche.createImage(size.width, size.height);
graphic = (Graphics2D) leinwandImage.getGraphics();
graphic.setColor(hintergrundfarbe);
graphic.fillRect(0, 0, size.width, size.height);
graphic.setColor(Color.black);
}
fenster.setVisible(sichtbar);
}
/**
* Zeichne für das gegebene Figur-Objekt eine Java-Figur (einen Shape) auf
* die Leinwand.
*
* @param figur
* das Figur-Objekt, für das ein Shape gezeichnet werden soll
* @param farbe
* die Farbe der Figur
* @param shape
* ein Objekt der Klasse Shape, das tatsächlich gezeichnet wird
*/
public void zeichne(Object figur, String farbe, Shape shape) {
figuren.remove(figur); // entfernen, falls schon eingetragen
figuren.add(figur); // am Ende hinzufügen
figurZuShape.put(figur, new ShapeMitFarbe(shape, farbe));
erneutZeichnen();
}
/**
* Entferne die gegebene Figur von der Leinwand.
*
* @param figur
* die Figur, deren Shape entfernt werden soll
*/
public void entferne(Object figur) {
figuren.remove(figur); // entfernen,falls schon eingetragen
figurZuShape.remove(figur);
erneutZeichnen();
}
/**
* Setze die Zeichenfarbe der Leinwand.
*
* @param farbname
* der Name der neuen Zeichenfarbe.
*/
public void setzeZeichenfarbe(String farbname) {
if (farbname.equals("rot")) {
graphic.setColor(Color.red);
} else if (farbname.equals("schwarz")) {
graphic.setColor(Color.black);
} else if (farbname.equals("blau")) {
graphic.setColor(Color.blue);
} else if (farbname.equals("gelb")) {
graphic.setColor(Color.yellow);
} else if (farbname.equals("gruen")) {
graphic.setColor(Color.green);
} else if (farbname.equals("lila")) {
graphic.setColor(Color.magenta);
} else if (farbname.equals("weiss")) {
graphic.setColor(Color.white);
} else {
graphic.setColor(Color.black);
}
}
/**
* Warte für die angegebenen Millisekunden. Mit dieser Operation wird eine
* Verzögerung definiert, die für animierte Zeichnungen benutzt werden kann.
*
* @param millisekunden
* die zu wartenden Millisekunden
*/
public void warte(int millisekunden) {
try {
Thread.sleep(millisekunden);
} catch (Exception e) {
// Exception ignorieren
}
}
/**
* Zeichne erneut alle Figuren auf der Leinwand.
*/
private void erneutZeichnen() {
loeschen();
for (Object figur : figuren) {
figurZuShape.get(figur).draw(graphic);
}
zeichenflaeche.repaint();
}
/**
* Lösche die gesamte Leinwand.
*/
private void loeschen() {
Color original = graphic.getColor();
graphic.setColor(hintergrundfarbe);
Dimension size = zeichenflaeche.getSize();
graphic.fill(new Rectangle(0, 0, size.width, size.height));
graphic.setColor(original);
}
/***************************************************************************
* Interne Klasse Zeichenflaeche - die Klasse für die GUI-Komponente, die
* tatsächlich im Leinwand-Fenster angezeigt wird. Diese Klasse definiert
* ein JPanel mit der zusätzlichen Möglichkeit, das auf ihm gezeichnet Image
* aufzufrischen (erneut zu zeichnen).
*/
private class Zeichenflaeche extends JPanel {
private static final long serialVersionUID = 20060330L;
public void paint(Graphics g) {
g.drawImage(leinwandImage, 0, 0, null);
}
}
/***************************************************************************
* Interne Klasse ShapeMitFarbe - Da die Klasse Shape des JDK nicht auch
* eine Farbe mitverwalten kann, muss mit dieser Klasse die Verknüpfung
* modelliert werden.
*/
private class ShapeMitFarbe {
private Shape shape;
private String farbe;
public ShapeMitFarbe(Shape shape, String farbe) {
this.shape = shape;
this.farbe = farbe;
}
public void draw(Graphics2D graphic) {
setzeZeichenfarbe(farbe);
graphic.fill(shape);
}
}
}
private void erneutZeichnen() {
loeschen();
synchronized (figuren)
{
for (Object figur : figuren) {
figurZuShape.get(figur).draw(graphic);
}
}
zeichenflaeche.repaint();
}
for (Object figur : figuren) {
figurZuShape.get(figur).draw(graphic);
}
public void run()
{
zeichnen1();
animation1();
}
Versuch's mal so:Maxga hat gesagt.:wir hatte im Unterricht heute eine Aufgabe, 2 Methoden quasi parallel ausführen zu lassen.
label1 = new JLabel("label1");
label2 = new JLabel("label2");
setLayout(null);
label1.setBounds(50, 50, 100, 30);
label2.setBounds(150, 80, 100, 30);
add(label1);
add(label2);
timer1 = new javax.swing.Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label1.setLocation(label1.getLocation().x + 1, label1.getLocation().y);
}
});
timer2 = new javax.swing.Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
label2.setLocation(label2.getLocation().x + 1, label2.getLocation().y);
}
});
timer1.start();
timer2.start();
public void langsamHorizontalBewegen(int entfernung)
{
....
for (int i = 0; i < entfernung; i++) {
xPosition += delta;
zeichnen();
}
}
Exception in thread "Thread-14" java.lang.NullPointerException
at Leinwand.erneutZeichnen(Leinwand.java:196)
at Leinwand.zeichne(Leinwand.java:132)
at Quadrat.zeichnen(Quadrat.java:204)
at Quadrat.sichtbarMachen(Quadrat.java:88)
at Loesung.run(Loesung.java:24)
at java.lang.Thread.run(Thread.java:619)
Exception in thread "Thread-15" java.lang.NullPointerException
at Leinwand.erneutZeichnen(Leinwand.java:196)
at Leinwand.zeichne(Leinwand.java:132)
at Kreis.zeichnen(Kreis.java:206)
at Kreis.sichtbarMachen(Kreis.java:56)
at KreisAnimator.zeichnen(KreisAnimator.java:21)
at KreisAnimator.run(KreisAnimator.java:32)
at java.lang.Thread.run(Thread.java:619)