• Keine Ergebnisse gefunden

Hier muss die Schleife nicht 25 mal durchlaufen werden, denn sobald ein weißer Kreis gefunden ist, steht fest, dass das Puzzle noch nicht gelöst ist. Die Schleife wird solange (=while) durchlaufen, wie

gelöst wahr ist, und außerdem i<25 gilt. Nur wenn i=25 erreicht wird, ist das Puzzle gelöst.

Dieser Schleifentyp besteht aus dem Schleifenkopfwhile (<Wiederholungsbedingung>) und dem Schleifenkörper, der von geschweiften Klammern eingeschlossen ist. Der Schleifenkörper wird

public void paint(Graphics g) {

int a = 10*Kreis.r+2*Kreis.rand; // Spielfeld-Kantenlänge // while-Schleife: Anfang

solange immer wieder durchlaufen, bis die Wiederholungsbedingung nicht mehr erfüllt ist.

Die in der Schleife verwendeten Variablen müssen vor Schleifenbeginn deklariert und initialisiert sein (i = 0), die Erhöhung des laufenden i erfolgt innerhalb des Schleifenkörpers (i++). Letzteres wird leicht vergessen – dann hat man meistens eine „Totschleife“ programmiert, die nie verlassen wird, das Applet „hängt sich auf“ und muss „gewaltsam“ beendet werden!

In Kapitel 9 können Sie nachlesen, wie while-Schleifen oft durch for -Schleifen ersetzt werden können!

Es folgt der letzte Teil des Applet-Quelltextes, der sich durch die Kommentare selbst erklärt:

Die Zeile und die Spalte des eventuell getroffenen Kreises ergeben sich durch Division von (Mauskoordinate – Rand) durch Kreisdurchmesser. Nachkommastellen werden bei der Zuweisung an eine Ganzzahl-Variable abgeschnitten. Aus Zeile und Spalte lässt sich leicht der Index des in Frage kommenden Kreises berechnen. Die Methode mousePressed ruft am Schluss meldung() auf, damit nach jedem Klick die Prüfung erfolgt, ob das Puzzle gelöst ist.

Rufen Sie das Applet mit einer Höhe von 434 und einer Breite von 406 (=5*Durchmesser+2*Rand) auf! Versuchen Sie Ihr Glück, nutzen Sie die Möglichkeit des Neustarts mit dem Menü des Applet-viewers! Viel Spaß beim Spielen!

Zum Weitergeben lassen Sie BlueJ die html-Seite erzeugen und bearbeiten Sie die Datei

Puzzle.html mit dem Windows-Editor so, wie auf Seite 26 beschrieben. Der Anwender muss diese Datei und die Dateien Puzzle.class, Kreis.class, Puzzle$MeinMausAdapter.class im selben Ordner speichern, um das Spiel im Browser ausführen zu können.

// Meine MausAdapter-Klasse mit mousePressed-Methode:

private class MeinMausAdapter extends MouseAdapter {

public void mousePressed(MouseEvent e) {

int x = e.getX(); // Mausposition holen int y = e.getY();

// Zeile und Spalte ermitteln:

int spalte = (x-Kreis.rand) / (2*Kreis.r);

int zeile = (y-Kreis.rand) / (2*Kreis.r);

// Index des Keises, der getroffen sein könnte:

int nr = 5*zeile + spalte;

// Wenn getroffen, dann Farbe wechseln:

if (dieKreise[nr].istdrin(x,y)

&& e.getButton() == MouseEvent.BUTTON1) {

Graphics gra = getGraphics();

dieKreise[nr].farbWechsel(gra);

// Nachbarfeld-Farbwechsel, soweit nötig:

if (spalte > 0)

dieKreise[nr-1].farbWechsel(gra);

if (spalte < 4)

dieKreise[nr+1].farbWechsel(gra);

if (zeile > 0)

dieKreise[nr-5].farbWechsel(gra);

if (zeile < 4)

dieKreise[nr+5].farbWechsel(gra);

}

meldung();

} }

} // abschließende Klammer der Klasse Puzzle

Quelltext der Klasse Puzzle, Teil 6 Quelltext der Klasse Puzzle, Teil 6

9. Was haben wir jetzt gelernt? (Wdh. und kleine Ergänzungen)

Sie haben in den vorangegangenen Kapiteln Grundlagen der Programmiersprache JAVA kennen gelernt. Hier können Sie zur Wiederholung nachlesen, wie ein JAVA-Quelltext aufgebaut ist:

Klassen: Jeder Quelltext definiert eine Klasse und hat folgende Form:

Instanzen der Klasse werden mit new <Klassenname>([Parameter]) erzeugt, siehe auch Konstruktor. Es ist üblich, Klassennamen mit einem Großbuchstaben zu beginnen.

Variablen werden in der Form

definiert, also indem zuerst der Typ und dann der Variablenname festgelegt werden, z.B. int a;

oder String s = "Informatik"; oder double c = -3.08;

Für die Zugriffsberechtigung verwenden wir meistens private oder public, sie kann auch als

protected festgelegt werden, sie darf auch fehlen.

Wenn der Typ eine Klasse ist, stellt die Variable genaugenommen einen Zeiger (eine Referenz) auf eine Instanz dieser Klasse dar. Es ist üblich, Variablennamen mit einem Kleinbuchstaben zu beginnen.

Methoden werden in folgender Form definiert:

Der Rückgabetyp gibt an, was die Methode liefert (einen String? Eine Gleitkommazahl?), sofern sie denn einen Wert zurück gibt. Bei Methoden ohne Rückgabewert muss hier void angegeben werden.

Bei Methoden mit Rückgabewert muss der Methodenquelltext stets auf eine return-Anweisung führen.

Die Parameterliste legt fest, welche Arten von Daten an die Methode übergeben werden sollen.

Dabei wird immer erst der Typ, dann ein Variablenname genannt. Mehrere Parameter werden durch Komma getrennt. Beim Methodenaufruf werden Werte (oder Zeiger) an die Methode übergeben, die Methode verwendet gemäß Parameterliste lokale Variablen, um mit diesen Werten zu arbeiten. Die Parameterliste darf auch leer sein, die Klammern müssen dann trotzdem stehen.

Ein Beispiel: Die Lösung von Aufgabe 17 auf Seite 20 (ganz ähnlich ist die Lösung von Aufgabe 24).

public void setName(String v, String n) {

vorname = v; // Datenfeld vorname erhält Wert der lokalen Variablen v, nachname = n; // nachname erhält entsprechend Wert von n.

}

<Import-Anweisungen soweit erforderlich>

public class <Klassenname> [optional: extends <Vorgängerklasse>]

{

<Bereitstellung von Variablen (Instanzvariablen / Klassenvariablen>

<Methoden (auch der Konstruktor ist eine Methode)>

[optional: weitere Klassendefinition, z.B. MausAdapter]

}

<Zugriffsberechtigung><Typ> <Name> [optional: Wertzuweisung];

<Zugriffsberechtigung> <Rückgabetyp> <Name>(<Parameterliste>) {

<Methodenquelltext, bei Bedarf mit Bereitstellung von lokale Variablen>

[ggf. return-Anweisung]

}

Es ist üblich, Methodennamen mit einem Kleinbuchstaben zu beginnen.

Ein Beispiel für die Verwendung von lokalen Variablen, die erst innerhalb der Methode definiert werden, zeigt die Klasse „Bank“ in ihrer Methode überweisen. Der für die lokalen Variablen reservierte Speicherplatz wird mit Abschluss der Methode frei gegeben, diese Variablen existieren dann nicht mehr.

Es können mehrere Methoden mit demselben Namen definiert werden, wenn sie sich in den Parameterlisten unterscheiden (Vergl. Konstruktoren).

Konstruktoren sind spezielle Methoden, deren Syntax geringfügig von der zuvor beschriebenen abweicht. Sie werden in der Form

definiert. Die Zugriffsberechtigung ist meistens public. Da der Methodenname hier mit dem Klassennamen übereinstimmt, wird für die Rückgabe kein Typ genannt, es gibt auch keine return -Anweisung: Der Aufruf erfolgt mit dem Schlüsselwort new und damit wird eine Instanz dieser Klasse (genau genommen: ein Zeiger darauf) zurückgegeben.

Eine Klasse kann mehrere Konstruktoren besitzen. Wird kein Konstruktor programmiert, so kann der geerbte Konstruktor mit leerer Parameterliste zum Erzeugen von Instanzen verwendet werden.

Zugriff auf Daten / Methoden anderer Objekte:

Für den Zugriff auf Methoden oder Variablen, die nicht Teil der aktuellen Instanz sind, wird der Bezeichner des Objekts (z.B. eines Bankkontos, eines Kreises, einer Graphics-Instanz) vorangestellt und ein Punkt als Trennzeichen gesetzt. Beispiel: dieKreise[i].zeichnen(g);

Programmstrukturen

Fallunterscheidungen werden mit if bzw. mit if ... else programmiert, die Form ist:

Der else-Teil ist optional, das heißt, er darf fehlen.

Wenn der Quelltext eines dieser Fälle nur aus einer einzigen Anweisung besteht, dürfen dessen geschweiften Klammern fehlen.

Eine ergänzende Anmerkung: Da die return-Anweisung eine Methode sofort beendet, darf bei der Altersberechnung der Klasse „Person“ das else fehlen:

if (hatteSchonGeburtstag)

return heute.get(Calendar.YEAR)–geburtsDatum.get(Calendar.YEAR); //Schluss!

return heute.get(Calendar.YEAR) - geburtsDatum.get(Calendar.YEAR) - 1;

Das erste return wird erreicht, wenn hatteSchonGeburtstag wahr ist, sonst das zweite. Bilden Sie sich selbst ein Urteil über die Verständlichkeit eines solchen Quelltextes.

Für Fallunterscheidungen mit mehr als zwei Fällen kann die switch-Anweisung hilfreich sein, auf die aber in diesem Text nicht eingegangen wird.

<Zugriffsberechtigung> <Klassenname>(Parameterliste) {

<Konstruktorquelltext> // Initialisierung }

if (<Bedingung>) {

<Quelltext für Wenn-Fall>

} else {

....<Quelltext für Sonst-Fall>

}

Schleifen

Syntax der for-Schleife:

for (<Schleifenvariable mit Startwert>; <Wiederholungsbedingung>; <Änderungsanweisung für die Schleifenvariable>) {<zu wiederholende Anweisungen>}

Die Schleifenvariable kann innerhalb der runden Klammer deklariert werden, dann ist sie nur inner-halb der Schleife gültig. Sie kann aber auch schon vorher definiert sein, dann kann ihr (veränderter) Wert nach Verlassen der Schleife weiter verwendet werden.

Syntax der while-Schleife:

while (<Wiederholungsbedingung>) {<zu wiederholende Anweisungen>}

Bei diesem Schleifentyp müssen die zu wiederholenden Anweisungen dafür sorgen, dass die Wiederholungsbedingung nicht dauerhaft erfüllt bleibt!

Beispiel: Die while-Schleife in der Methode meldung() aus dem Quelltext der Klasse Puzzle

(S. 35) kann elegant durch folgende for-Schleife ersetzt werden:

for (int i = 0; geloest && i<25; i++) // Abbruch, wenn Kreis nicht rot ist!

{

geloest = dieKreise[i].istRot();

}

10. Schlussbemerkung

BlueJ ist für die hier vorgestellten Projekte eine gut geeignete Entwicklungsumgebung, insbe-sondere durch die Möglichkeit, Instanzen zu „inspizieren“ und ihre Methoden ohne Program-mierung eines Menüs aufrufen zu können. Auch der Zugriff einer Instanz auf eine andere Instanz (Projekt „Bank“) lässt sich gut demonstrieren. Für den Einstieg in JAVA ist BlueJ daher eine gute Wahl.

Andere Entwicklungsumgebungen haben andere Vorteile, sie bieten z.B. Unterstützung bei der Layout-Gestaltung eines Applets, sie erlauben den bequemen Einbau eines Menüs oder von Schaltflächen für Programmaktionen. Beispiele sind die Programme „Java-Editor“ und „NetBeans“, die wie BlueJ ebenfalls kostenlos aus dem Internet heruntergeladen werden können.

Beide Programme bieten auch eine Code-Vervollständigung an: Wenn man in diesen Entwicklungs-umgebungen bei unserem Puzzle-Quelltext (Kapitel 8) den Klassenbezeichner „Kreis.“ eintippt, wird sofort die Auswahl der möglichen Methoden oder Variablen angezeigt, die in dieser Klasse verfügbar (also public) sind. Dieser Vorteil zeigt sich auch z.B. bei der Verwendung eines Graphics-Objektes: Sobald man den Bezeichner und den anschließenden Punkt getippt hat, kann man schon sehen, welche Methoden dieses Objekt besitzt (drawrect, fillrect, drawtext usw.) – außerdem werden die benötigten Parameter angezeigt. Dadurch kann man sich oft das Nachlesen in der Doku-mentation zu den verwendeten Klassen ersparen.

Das Programm „Java-Editor“ beansprucht deutlich weniger Ressourcen als „NetBeans“ und ist zum Erstellen kleiner Programme gut geeignet. Automatisch erstellter Quelltext kann jedoch so verändert werden, dass es zu Unstimmigkeiten zwischen Layout-Entwurf und Aussehen des Programm-Fensters kommen kann. „NetBeans“ hat dagegen ein so umfangreiches Menü, dass Anfänger es schon beim Erstellen und Speichern ihres ersten Projekts schwer haben; diese Entwicklungsumgebung ist sehr professionell und eignet sich gut für komplexe Anwendungen.

Je anspruchsvoller Programme werden, umso mehr zeigen sich die Vorteile der hier genannten Entwicklungsumgebungen.

While-Schleifen können oft durch for-Schleifen ersetzt werden, weil die Wiederholungs-bedingung auch unabhängig von der Schleifenvariablen formuliert werden kann, sie kann auch eine Kombination mehrerer Bedingungen sein.