Skript Java für Förster

Werbung
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 1 von 48
Skript Java für Förster
Technologie der Informationsverarbeitung im Schwerpunkt Waldökosystemanalyse u. Informationsverarbeitung
© 2001-2003
Prof. Dr. Jürgen Nagel
http://www.gwdg.de/~jnagel
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 2 von 48
EINLEITUNG ............................................................................................................................................................. 3
MOTIVATION............................................................................................................................................................. 3
ORGANISATORISCHES ............................................................................................................................................... 4
GRUNDLAGEN.......................................................................................................................................................... 5
EINFÜHRUNG IN DIE PROGRAMMIERSPRACHE ........................................................................................................... 5
DATENORGANISATION .............................................................................................................................................. 6
LITERATUR UND INTERNET ....................................................................................................................................... 6
VORBEREITUNG ........................................................................................................................................................ 7
DAS ERSTE PROGRAMM ............................................................................................................................................ 8
DIE GRUNDRECHENARTEN ...................................................................................................................................... 10
DATENTYPEN .......................................................................................................................................................... 11
KONDITIONALE ANWEISUNGEN .............................................................................................................................. 13
SCHLEIFEN .............................................................................................................................................................. 14
ARRAYS .................................................................................................................................................................. 17
KLASSEN.................................................................................................................................................................. 18
ZWECK UND AUFBAU .............................................................................................................................................. 18
EINFACHES KLASSENBEISPIEL ................................................................................................................................ 20
HÜLLKLASSEN UND UMWANDELN VON DATENTYPEN ............................................................................................ 25
KLASSE MATH ........................................................................................................................................................ 26
KLASSE DECIMALFORMAT...................................................................................................................................... 27
LESEN UND SCHREIBEN AUS DATEIEN ......................................................................................................... 29
JAVA API.................................................................................................................................................................. 36
GRAFIK .................................................................................................................................................................... 36
DOKUMENTATION MIT JAVADOC ............................................................................................................................. 44
WEITERGABE .......................................................................................................................................................... 44
INDEX........................................................................................................................................................................ 48
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 3 von 48
Einleitung
Motivation
Der Kurs nennt sich Java für Förster (JAFF) und ist als Einführung in die Programmierung
gedacht. Warum könnte überhaupt ein Förster um alles in der Welt ein Interesse daran haben,
programmieren zu lernen? Reicht es nicht aus, wenn er draußen im Wald ist? Sicher ist, daß sich
diese Frage nicht eindeutig beantworten läßt. Aber in den letzten Jahren hat sich das Berufsbild
erheblich verändert. Vorbei ist die Idylle. Rationalisierung und Produktivitätsfortschritt sind in
einer nachhaltigen multifunktionalen Forstwirtschaft gefordert, die zunehmend einen Ausgleich
zwischen den Interessen verschiedender Gruppen und Verbände anstreben muß. Kein Wunder,
daß moderne Informationstechnologien auch die abgelegensten Forsthäuser erreicht haben und
der Computer zum alltäglichen Werkzeug für die Betriebsführung, die Planung und die
Präsentation geworden ist. Darüber hinaus gibt es heute eine wachsende Zahl von "Förstern", die
als Freiberufliche ihren Lebensunterhalt mit z.T. wechselnden Aufgaben verdienen. In den
meisten Fällen sind dabei gute Kenntnisse im Umgang mit Textverarbeitung,
Tabellenkalkulation, Datenbanken und Präsentationsprogrammen unumgänglich. Häufig kommt
es vor, daß der Datenfluß vom einen zum anderen Standardprogramm am Format hapert oder
kleine Details mit diesen Programmen nicht oder nur aufwendig ausgewertet werden können.
Genau für diese Fälle soll der Kurs eine Hilfe zur Selbsthilfe sein. Gleichzeitig wird er aber auch
ein besseres Verständnis in den Umgang mit Computerprogrammen vermittelt.
Es gibt viele Sprachen mit denen man Computerprogramme schreiben kann. Die Elemente dieser
Sprachen sind weitgehend ähnlich und daher ist es für die meisten Programmierer auch nicht zu
schwierig, von einer auf die andere Programmiersprache umzulernen. In diesem Kurs soll das
Programmieren mit der Sprache Java erlernt werden. Es handelt sich dabei um eine moderne und
objektorientierte Sprache, die sich auch gut für Internetanwendungen einsetzen läßt. Der größte
Vorteil der Sprache Java ist aber der, daß die geschriebenen Programme auf verschiedenen
Betriebssystemen (DOS, Windows, LINUX, etc.) eingesetzt werden können. Es gilt daher der
Grundsatz „write once and use multiple“.
Für die Programmierung mit Java gibt es zwar eine Reihe hilfreicher Entwicklungsumgebungen
wie den JBuilder (Borland) und Forte (Sun). Aber die Grundlagen lassen sich besser ohne eine
solche Entwicklungsumgebung erklären. Man benötigt lediglich das Java Development Kit der
Firma Sun, welches kostenfrei aus dem Internet zugänglich ist. Wenn man dann die Grundlagen
von Java beherrscht und auf die zahlreichen vorhandenen Funktionen und Möglichkeiten der
Sprache bequemer zugreifen möchte, kann man leicht und mit dem nötigen Verständnis auf eine
solche Entwicklungsumgebung umsteigen.
Der Kurs ist auf Studenten des Forststudiums ausgerichtet und nennt sich daher Java für Förster.
In den Beispielen werden forstliche Probleme bearbeitet. Über den gesamten Kurs soll ein
einfaches Wachstumsmodell mit Oberfläche und Grafik entstehen, in dem alle wichtigen und
grundlegenden Bereiche der Programmierung mit Java verdeutlicht werden. Dieses einfache
Wachstumsmodell kann als Grundlage für weitere Anwendungen verwendet werden. Der Kurs
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 4 von 48
ist aber auch für Studenten anderer Fachbereiche geeignet, die sich Programmierkenntnisse für
kleine Problemlösungen aneignen möchten.
Programmieren kann man nur durch selbstständiges programmieren lernen. Daher sollten Sie die
Kapitel sorgfältig durcharbeiten und Sie sollten die Übungsaufgaben lösen. Ich empfehle Ihnen
auch den Code abzutippen und zu verstehen. Mit „cut and paste“ (ausschneiden und einfügen)
geht es schneller, aber häufig leidet darunter das Verständis. Dazu ist eine gewisse Portion
Hartnäckigkeit gefragt. Aber aus Fehlern kann man nur lernen. Es ist nicht der Computer der Sie
ärgern will, es liegt fast immer an Ihnen, wenn Ihr Programm nicht das ausführt, was Sie gerne
möchten. Beweisen Sie sich, daß Sie es können! Hat man erst mal einige Programme selbst
erstellt, kann man auf diese Grundgerüste bei neuen Aufgaben immer wieder zurückgreifen. In
dem Sinne ist auch dieser Kurs aufgebaut. In einigen kleinen Programmen werden Ihnen
zunächst die Grundlagen vermittelt. Daran schließen sich einige größere Projekte an, die auf
diesen Grundlagen aufbauen. Die größeren Projekte wiederum können Ihnen als Beispiel dienen,
wenn Sie eigene umfangreiche Projekte realisieren wollen.
Organisatorisches
Laden Sie sich zunächst die Java 2 Platform, Standard Edition (J2SE)1 und die dazugehörige
Dokumentation für Ihr Betriebsystem (Windows, Mac, Linux, etc..) aus dem Internet und
installieren Sie das Programm und die Dokumentation (http://java.sun.com/j2se/).
Legen Sie sich ein Unterverzeichnis JAFF an. In dieses Verzeichnis wollen wir die
Beispielprogramme schreiben. Sie finden die Beispielprogramme im Ordner jaff\example.
Versuchen Sie jedoch immer zuerst die Programme selber zu schreiben. Entgegen der sonstigen
Geflogenheit die Klassennamen und die dazugehörigen Dateinamen von Java mit einem großen
Buchstaben beginnen zu lassen, habe ich mich entschieden, alle Dateinamen lieber nur klein
zu schreiben. Dies ist zwar nicht ganz so übersichtlich, hat jedoch den Vorteil, daß es beim
Kopieren und Entpacken der Dateien nicht zu einer systembedingten Änderung der Groß- und
Kleinschreibung kommt und damit die Dateien leichter von Windows auch auf das
Betriebssystem Linux übertragen werden können, ohne daß man die Benamung hinterher wieder
ändern muß.
Im weiteren Text finden sie einige Begriffe, die fett geschrieben sind. Dies sind wichtige
Begriffe für das weitere Verständis. Wenn Sie auf grünen, fetten Text in Times New Roman 10
stoßen, so handelt es sich um Programmcode. Zu jedem Programmbeispiel gehört meist ein
eigenes Java Programm. Die Programme sind z.B. mit p1 usw. benannt. Benennen Sie Ihre
Programm möglichst genauso. Programmausgaben sind in fetten Text in Times New Roman 10. Rot
und fett geschriebener Text gibt Ihnen nur wichtige Tips. Dunkelblau in Courier 10 sind Daten. Die
Projekte werden in eigenen Verzeichnissen gespeichert.
Falls Sie Fehler in diesem Text entdecken, wäre es nett, wenn Sie diese mitteilen würden. Falls
1
Die Java 2 Platform, Standard Edition (J2SE), die dazugehörige Dokumentation und aller Beispielprogramme
finden Sie auch auf der CD-ROM Forest Tools ab der Version SS02. Für mehr Informationen und zum Bestellen der
CD sehen Sie bitte auf dem Internet unter http://www.gwdg.de/~jnagel/cdft.html nach.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 5 von 48
Sie Verbesserungsvorschläge haben, so sind diese auch willkommen. Schicken Sie eine E-Mail
an: [email protected]
Grundlagen
Einführung in die Programmiersprache
Computer (ursp. von lat. computare = berechnen) sind universell arbeitende Geräte zur
Verarbeitung von Informationen. Einen Computer kann man zur Erfüllung verschiedener
Aufgaben verwenden, z.B. zum Rechnen, zur Textverarbeitung, zur Steuerung von Maschinnen
und zum Spielen. Dazu benötigt der Computer nur das richtige Programm zur Steuerung der
Abläufe.
Ein Algorithmus ist ein allgemeines Verfahren zur Lösung einer Folge gleichartiger Probleme.
Diese besteht aus einer Folge von Anweisungen, die präzise formuliert sind. Ein Algorithmus
kann also auch von Menschen oder Maschinen ausgeführt werden, die die Anweisungen genau
verstehen. Einem Computer müssen die Anweisungen in geeigneter Form zur Verfügung gestellt
werden. Dazu gibt es die Programmiersprachen.
Ein Computerprogramm ist die Formulierung eines Algorithmus entsprechend den Regeln einer
Programmiersprache. Die Syntax ist das Regelwerk einer Programmiersprache und definiert,
welche Texte in der jeweiligen Programmiersprache gelten. Die Semantik definiert die
Bedeutung der einzelnen Sprachelemente. Wer die Syntax und die Symantik kennt, kann
Computerprogramme lesen und verstehen. Die Programmiersprache dient also der
Verständigung zwischen Menschen und zwischen Mensch und Maschine, in dem ein
Algorithmus formalisiert beschrieben wird.
Die eigentliche Sprache, die ein Computer versteht, ist die Maschinensprache. Man kann
Rechner direkt in Maschinensprache programmieren, indem man einen Assembler verwendet.
Dies ist jedoch unübersichtlich und nicht produktiv. Die Maschinensprache ist darüber hinaus
vom Prozessor des Computers abhängig. Man kann nun die Maschinensprache auf zwei Wege
umgehen. Erstens übersetzen Compiler eine verständlichere Sprache in Maschinenanweisungen
und zweitens können Interpreter die Anweisungen einer Sprache lesen und dann zu jeder
Anweisung eine Anzahl von Maschinenbefehlen ausführen. Die bekanntesten höheren
Programmiersprachen sind C, C++, Pascal (Delphi), (Visual) Basic und Fortran. Sie verfügen
über Compiler. Als Interpreter Sprachen lassen etwa Access und Excel Skripte verstehen. Java
ist eine Sprache die zwischen Compilier und Interpreter einzuordnen ist. Das compilierte JavaProgramm ist vom Prozessor unabhängig und die Interpretation des Byte-Code kann
wesentlich schneller erfolgen als die direkte Interpretation des Programmtextes. Java hat in den
letzten Jahren als Sprache an Bedeutung gewonnen, weil sie auch vom Betriebssystem des
Computers (DOS, Windows, Unix) unabhängig ist.
In diesem Skript wird nun an einfachen Beispielen die Programmierung mit Java verdeutlicht.
Die Beispiele sind für das Betriebssystem Windows meist im DOS Fenster erklärt. Sie können
aber auch leicht unter Unix oder Linux nachvollzogen werden. In den Anfangsbeispielen wird
bewußt auf eine Java Entwicklungsumgebung verzichtet, damit die Grundlagen von Java klarer
werden.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 6 von 48
Datenorganisation
Die Daten auf einer Festplatte sind in Dateien (Files) organisiert. Meist ist eine Festplatte
hierarchisch in Verzeichnisse untergliedert. An der Spitze steht unter DOS das
Wurzelverzeichnis (root) eines Laufwerks (drive). Jedes Laufwerk hat einen eigenen Namen,
den Laufwerksbuchstaben. Die 1. Festplatte wird meist mit C: angesprochen. Verzeichnisse
werden durch Schrägstriche \ abgegrenzt. Unter Unix wird der entgegengesetzte Schrägstrich
verwendet (/). Der Dateiname besteht unter DOS aus 8 Zeichen und einer Extension, die vom
Dateinamen durch einen Punkt abgesetzt ist.
C:\Unterverzeichnis\Unterunterverzeichnis\Datei.txt
Im DOS - Eingabefenster kann man mit den Befehlen:
DOS Befehl
cd ..
cd Unterverzeichnisname
mkdir Neuesverzeichnis
rmdir Verzeichnis
dir
Erklärung
in eine höhere Verzeichnisebene gelangen
ein Unterverzeichnis aufrufen
ein neues Unterverzeichnis anlegen
ein Unterverzeichnis löschen, wenn es leer ist
Anzeigen aller Dateien und Unterverzeichnisse des Verzeichnises
Möchte man unter DOS, daß das Betriebssytem ein spezielles Verzeichnis nach Programmen
durchsucht, wenn man in einem anderen Verzeichnis gerade arbeitet, so kann man dies mit dem
path Befehl erreichen. Man erweitert den path-Befehl für die Java-Programme mit der folgenden
Zeile:
path %PATH%;C:\jdk1.3.1_01\bin
Dies gilt natürlich nur, wenn Java auch in diesem Verzeichnis installiert ist.
Darüber hinaus sollte die Classpath Variable noch entsprechend eingestellt sein. Der Ausdruck
.; gibt an, daß zuerst das aktuelle Verzeichnis durchsucht werden soll.
SET CLASSPATH=.;c:\jdk1.3.0_02\lib
Beide Einstellungen können Sie bei Windows 95 bis ME dauerhaft festlegen, in dem Sie sie in
die Datei autoexec.bat schreiben.
Literatur und Internet
Dieses Skript erhebt nicht den Anspruch ein Lehrbuch zu ersetzen. In ihm werden lediglich
einige Grundlagen angesprochen und an Beispielen erklärt. Es soll insbesondere für den Typ von
Student eine Hilfe sein, der eine Programmiersprache nach dem Prinzip „Learning by doing“
erlernen möchte. In dem Skript werden nur die grundlegenden Elemente der Programmierung
erklärt, welche man zur Lösung spezieller forstlicher Algorithmen benötigt. Die Programmierung
von Benutzeroberflächen wird in diesem Skript nur an einigen wenigen Beispielen ansatzweise
erläutert, eine ausführliche Erklärung würde den Rahmen dieses Buches sprengen. Das gilt auch
für die Programmierung von Datenbanken.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 7 von 48
Wer jedoch die Grundlagen beherrscht und versteht, dem sollte es ein Leichtes sein, sich in die
Programmierung von Datenbanken und Benutzeroberflächen einzuarbeiten. Dabei sollte man
nicht den Ehrgeiz haben, und versuchen, alles von Grund auf alleine programmieren zu wollen.
Im Internet und im Buchhandel werden Sie zahlreiche Beiträge und Lehrbücher zur
Programmierung mit Java finden. In diesen findet man Beispiele und Programmteile, die man für
die Lösung der eigenen Probleme nutzen kann. Oft muss man nur kleine Veränderungen
durchführen. Für den Anfänger würde ich das Buch von Abts (2000) empfehlen. Das Buch von
Solymosi und Schmiedecke vertieft den Umgang mit Objekten, dazu sollte der Leser aber schon
gut mit Java vertraut sein.
•
•
Abts, D. (2000): Grundkurs Java. Vieweg Verlag, Braunschweig/Wiesbaden, 334S.
Solymosi, A.; Schmiedecke, I. (2000) :Programmieren mit Java. Vieweg Verlag,
Braunschweig/Wiesbaden, 356S.
Im Internet ist darüber hinaus eine große Anzahl von Online- Tutorien zu finden. In diesen findet
man z.T. gute Erklärungen und auch hilfreiche Beispiele. Sehr zu empfehlen ist der Java Kurs
von Grothmann der Universität Eichstätt.
•
http://mathsrv.ku-eichstaett.de/MGF/homes/grothmann/java/kurs
•
http://java.rrzn.uni-hannover.de/tkji/javakurs/kursdemos/index.html
•
http://www.galileocomputing.de/katalog/openbook?GalileoSession=59814873A1BgEhil.MQ
(hier kann man sich kostenlos ein ganzes Java-Buch herunterladen, wenn man sich keins kaufen
will)
•
oder anschauen: http://www.galileocomputing.de/openbook/javainsel3/
•
Wichtige Hinweise und Hilfestellungen zum Thema Java findet man auf den Seiten:
•
•
•
http://developer.java.sun.com/developer/support/
http://java.seite.net/
http://www.javaworld.com/
Vorbereitung
Bevor Sie jedoch anfangen, sollten Sie überlegen, wo Sie auf der Festplatte, dem permanenten
Speicher Ihres Computers, Ihre Java-Programm ablegen wollen, so dass Sie sie auch vielleicht
nach langer Zeit noch wieder finden können. Zu diesem Zweck kann der Speicher in
Verzeichnisse und Unterverzeichnisse eingeteilt werden. Es ist sinnvoll, wenn Sie Ihre Daten
von den Programmen trennen, denn wenn Sie z.B. eine neue Version eines
Textverarbeitungsprogramms wie Word auf Ihren Computer bringen, können Sie die alte
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 8 von 48
Version vorher löschen, ohne dass Ihrer Texte aus Versehen verloren gehen, wenn die Texte in
einem separaten Verzeichnis gespeichert sind. Darüber hinaus können Sie auch eine
Sicherheitskopie Ihrer Texte leichter anfertigen, indem Sie einfach das entsprechende
Verzeichnis kopieren. Daher sollten Sie auch Ihre Java Übungsprogramme in ein eigenes
Verzeichnis stellen.
Erstellen Sie ein Unterverzeichnis JAFF (Java für Förster) in DOS oder Windows. Dieses
Verzeichnis wird für die nächsten Übungen Ihr Java Arbeitsverzeichnis.
Das erste Programm
Programm p1.java: Mein erstes Programm
Aufgabe: Wir wollen ein Programm schreiben, welches auf den Bildschirm die Zeile „ auch
Förster lernen programmieren“ schreibt.
Algorithmus: Er besteht in diesem Fall für uns aus einem einzigen Befehl, nämlich schreibe die
Zeile „auch Förster lernen programmieren“.
Programmierung: Schreiben Sie die folgenden Zeilen des Programms p1.java mit einem
Texteditor in eine Datei und speichern Sie den Text als ASCII-Datei mit dem Namen p1.java ab.
Dafür kann der Windows Benutzer z.B. das Programm Notepad verwenden. Es ist auch möglich
z.B. WinWord dafür zu verwenden, bei diesem Programm müssen Sie jedoch darauf achten, dass
Sie den Text als unformattiert abspeichern. Sonst enthält die Datei Steuerungszeichen mit denen
der Java Compiler nichts anfangen kann.
/* JAFF = Java fuer Foerster
Programm 1
Mehrzeiliger Kommentar
*/
public class p1
{ public static void main (String args[])
{ System.out.println("auch Foerster lernen programmieren");
}
}
Speichern Sie den Text in einer Datei unter dem Namen p1.java und öffnen Sie ein DOSFenster. Achten Sie unbedingt auf die Groß- und Kleinschreibung. Dos und Windows sind
da zwar nicht immer so wählerisch, aber Unix und Linux sind sehr empfindlich. Mancher
Fehler kommt einfach daher, daß p1 nicht gleich P1 ist.
Im DOS Fenster wählen Sie zuerst Ihr Verzeichnis JAFF (cd .. und cd jaff). Prüfen Sie mit dem
Befehl DIR, ob wirklich eine Datei p1.java existiert und auch p1.java heißt.
Nach dem dies erfolgreich geschehen ist, müssen Sie den Inhalt der Datei für den Java
Interpreter übersetzen. Dazu rufen Sie den Java-Compiler auf. Das Java Compiler Programm
heißt javac Dazu geben Sie den Befehl ein:
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 9 von 48
C:\jaff>javac p1.java
Lassen Sie sich nun mit dem Befehl Dir alle Dateien des Verzeichnisses jaff anzeigen. Sie
können hoffentlich feststellen, daß Sie eine 2. Datei mit dem Namen p1.class erzeugt haben.
Diese Datei enthält den Bytecode für den maschinenunabhängigen Bytecode-Interpreter von
Java.
Das Programm p1 können Sie nun beliebig oft ausführen, indem Sie die Datei p1.class mit dem
Befehl aufrufen:
C:\jaff>java p1
Es sollte auf dem Schirm die Zeile: auch Förster lernen programmieren erscheinen. Es mag sein, daß
das ö ein wenig anders aussieht, aber die Feinheiten unterschiedlicher Ländereinstellungen und
Code-Tabellen von Windows und DOS werden wir später besprechen. Die Datei p1.java können
Sie theoretisch löschen. Zum Ausführen des Programms benötigen Sie nur die *.class Dateien.
Die Datei p1.java möchten Sie aber dennoch nicht löschen, denn für den Fall, dass Sie später
einmal das Programm verändern wollen, müssen Sie auf die Datei p1.java zurückgreifen können.
Sehen wir uns das kleine Programm etwas näher an und besprechen erst mal nur einige Details.
Im Laufe des Kurses wird der Aufbau von Klassen noch genauer besprochen. Die geschweiften
Klammern markieren den Anfang und das Ende eines Blocks. In diesem Fall markiert der
Block den Beginn und das Ende der Klasse mit dem Namen p1.
public class p1
{
}
Es ist wichtig, dass der Klassenname (hier p1) und der Dateiname p1.java identisch auch in
Bezug auf die Groß- und Kleinschreibung sind. Jedes Java Programm besteht aus einer oder
mehreren Klassen. Die Hauptklasse muss eine Methode namens main haben. Sie muß public
sein, d.h. sie kann auch von anderen Klassen genutzt werden. Die geschweiften Klammern
markieren wieder Anfang und Ende, diesmal von der Methode main.
public static void main (String args[])
{
}
Durch das Hinzufügen der Methode main wird aus der Klasse ein Hauptprogramm. Eine
Methode ist ein in sich abgeschlossener Programmteil, der verschiedene Anweisungen enthalten
kann. Die Methode main muß public und static deklariert werden. Eine mit public deklarierte
Methode ist auch anderen Klassen zugänglich. Statische (static) Programmteile werden während
der gesamten Laufzeit geladen, während dynamische nur bei Bedarf geladen werden. Die
Methode main gibt kein Ergebnis zurück, daher void. Es kann, muß aber keine Zeichenketten
über die Variable args übernehmen. Aus diesem Grunde ignorieren wir vorerst String args[].
Nehmen Sie bitte an dieser Stelle die kurze Erklärung der Methode main als gegeben hin, und
konzentrieren Sie sich in den weiteren Beispielen zunächst auf den Text der zwischen die beiden
geschweiften Klammern der Methode main geschrieben wird. Im Skript wird noch ausführlich
auf den Sinn und Zweck von Methoden eingegangen.
System.out.println("auch Foerster lernen programmieren");
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 10 von 48
Diese Zeile ruft die Methode println der Klasse System.out auf. Die Klasse System.out wird
neben vielen anderen mit Java mitgeliefert und erlaubt einem, eine einfache Bildschirmausgabe
zu machen. Der Methode println() kann in der Klammer als Parameter ein String übergebenen
werden. Ein String ist eine Zeichenkette wie "auch Förster lernen programmieren". Sie werden in
Hochkomma ("") gesetzt. Println() schreibt diese Zeichenkette auf den Bildschirm. Eine
Kommandozeile wird in Java immer mit einem Semikolon (;) und nicht vom Zeilenende
begrenzt. Eine Kommandozeile kann daher auch auf mehrere Zeilen aufgeteilt werden.
Ein Zeilenkommentar kann durch 2 Schrägstriche // und ein mehrzeiliger Kommentar durch /*
und */ abgegrenzt werden. Kommentare sollten grundsätzlich in Programme geschrieben werden.
Sie helfen dem besseren Verständnis eines Programmes. Man kann auch einen
Dokumentationskommtentar verwenden, der den Kommentar für das Programm Javadoc
bereitstellt. In diesem Fall steht der Kommentar zwischen /** und */. Der
Dokumentationskommentar muß direkt vor der Klasse, Variablen oder Methode stehen, für die
er gilt.
Aufgaben: 1) Schreiben Sie selbstständig ein eigenes Programm, welches Ihren Namen ausgibt.
2) Machen Sie bewußt einige Fehler und beachten Sie die Meldungen des Compilers.
Die Grundrechenarten
Mit einem weiteren Programm wollen wir uns die Grundrechenarten verdeutlichen.
Programm p2.java: Einfache Rechenoperationen
Aufgabe: Das Programm soll eine Meldung „Einfache Rechenoperationen“ ausschreiben. Es soll
dann auf den folgenden Zeilen 2+2, 2*5, 11 : 4 und (2+2)*5 berechnet werden.
Algorithmus: Wie im Programm p1.java soll das Programm zuerst eine Textausgabe
durchführen. Danach soll es jeweils in einer Schreibanweisung den Text und die Lösungen für
die genannten Rechnenaufgaben auschreiben.
Programmierung: Schreiben Sie das Programm p2.java in eine separate Datei mit einem
Texteditor.
// JAFF = Einfache Rechenoperationen
public class p2
{ public static void main (String args[])
{ System.out.println("Einfache Rechenoperationen");
System.out.println("2+2= "+(2+2));
System.out.println("3*5= "+(3*5));
System.out.println("11/4="+(11/4));
System.out.println("11.0/4="+(11.0/4));
System.out.println("11.0/4.0="+(11.0/4.0));
System.out.println("(2+2)*5= "+((2+2)*5));
}
}
In diesem Programm haben wir im Vergleich zu p1.java einige zusätzliche Kommandozeilen
eingefügt. Sie demonstrieren die Grundrechenarten. Als arithmetische Operatoren gelten in
den Anweisungen folgende Zeichen:
Jaff : Java für Förster 01.12.03
+
*
/
()
J. Nagel
Seite 11 von 48
Addition
Substraktion
Multiplikation
Division
Klammern
In Java geht Punkt- vor Strichrechnung und die Klammer entsprechend.
Lassen Sie das Programm compilieren und starten Sie das Programm. Vielleicht überrascht das
Ergebnis von 11/4 gleich 2. Dieses Ergebnis ist nicht falsch, da wir mit ganzen Zahlen (Integer)
rechnen. Wird die Division mit zwei Integerzahlen durchgeführt, werden die Nachkommastellen
einfach vernachlässigt. Ist eine der beiden Zahlen ein relle Zahl, dieser Typ heißt in Java
(double), erhält man die „genauere“ Ausgabe. Dies ist eine Falle, der man sich als
Programmierer bewußt sein muß.
Der Text, der in der Methode System.out.println() ausgegeben wird, kann z.b. mit dem Ergebnis
einer Rechenoperation verkettet werden. Die Zeichenkette, die ausgegeben werden soll, steht in
Hochkommtar. Die Rechenoperation wird in Klammern gesetzt und mit dem Text verkettet. Die
Umwandlung der Integer bzw. double in eine Zeichenkette wird vom Programm automatisch
durchgeführt.
Aufgaben: 1) Schreiben Sie ein eigenes Programm und berechnen Sie folgendes: a) 5+6+7; b)
(5-2)*17, c) 15-6*12
Datentypen
Zur Speicherung von String (Zeichenketten), ganzen (int) und rellen Zahlen (double) benötigen
die Programme unterschiedlich viel Speicherbedarf. Den Typ einer Variable kann man in fast
allen Programmiersprachen an seine Bedürfnisse anpassen. Die wichtigsten Variablentypen sind:
Datentyp
short
int
float
double
byte
char
boolean
Erklärung
Ganze Zahl –215 .. 215
Ganze Zahl –231 .. 231
Gleitkomma Zahl ca,. 6-stellige Mantisse u. 2 stelliger Exponent
Gleitkomma Zahl ca,. 16-stellige Mantisse u. 3 stelliger Exponent
0..255
Zwei byte Zeichen in Unicode
Wahr (true) oder falsch (false)
Die Datentypen werden in dem nächsten Programm demonstriert.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 12 von 48
Programm p3.java: Datentypen
Aufgabe: Das Programm soll eine Meldung „Einfache Rechenoperationen“ ausschreiben. Es soll
dann auf den folgenden Zeilen 2+2, 2*5, 11 : 4 und (2+2)*5 berechnet werden. Diesmal sollen
allerdings Text und die Rechenoperationen nicht direkt im println eingegeben und berechnet
werden, sondern zuvor in Variablen gespeichert werden.
Algorithmus: Der Text und die Zahlen werden zunächst in Variablen gespeichert. Dafür soll
jeweils der entsprechende Datentyp verwendet werden. Dann erfolgt die Ausgabe wie in p2.java
Zeile für Zeile.
Programmierung: Schreiben Sie das Programm p3.java in eine separate Datei mit einem
Texteditor. Lassen Sie die Kommentare weg. Beachten Sie bitte die Kommentare. Einfache
Kommentare beginnen mit einem // und gelten zum Zeilenende. Alle Variablen, die man in
einem Programm benutzt, müssen in Java vorher erklärt bzw. erzeugt werden.
public class p3
{ public static void main (String args[])
{ int n; // Erzeugung einer Integervariable namens n
n=2; // Zuweisung des Wertes 2 zu n
int m=3; // Erklärung und Zuweisung auf einer Zeile
int k,l; // Erzeugung der zwei Integervariablen k und l
k= 3; l=5; // Zwei Zuweisungen
double x; // Erklärung einer double Variable namens x
double y=11.0; // Zuweisung des Wertes 11.0
String s="Einfache Rechen"; // Erklärung und Zuweisung einer Stringvariable s
// Ausschreiben der Variable s und zusätzliche Verkettung mit einem String
System.out.println(s+"operationen");
// Ausschreiben von m+n
System.out.println("2+2= "+(n+n));
System.out.println("3*5= "+(m*l));
// Berechnung von y/4 und Zuweisung nach x
x = y/4;
System.out.println("11/4="+x);
System.out.println("(2+2)*5= "+((n+n)*l));
System.out.println("exp(2)= "+(Math.exp(2)));
}
}
Die Variablen werden vor der Verwendung in dem Unterprogramm durch den Datentyp gefolgt
vom Variablennamen deklariert. Mehrere Variablen eines Typs kann man durch die Trennung
mit einem Komma in einer Kommandozeile definieren. Es lassen sich den Variablen auch sofort
Werte zuweisen. In dem Programm finden sich auch einfache Kommandozeilen, in denen nur
gerechnet wird. Die Methode exp der Klasse Math berechnet den Exponenten. Die Klasse Math
wird mit Java geliefert und enthält zahlreiche nützliche mathematische Funktionen (s. Kap.
Klassen).
Aufgabe: Berechnen Sie das Volumen [m³] für eine Eiche mit einem BHD von 30 cm und einer
Höhe von 20 m. Benutzen Sie dazu die Formzahlfunktion von Bergel (Der Durchmesser wird in
der Formel in der Maßeinheit cm und die Höhe in m eingesetzt):
Jaff : Java für Förster 01.12.03
f = 0.4786 −
J. Nagel
Seite 13 von 48
1.0111 2.104 203.12
+
−
d
h
d ⋅ h2
Konditionale Anweisungen
In der Programmierung sind konditionale Anweisungen ein wichtiges Element zur Verzweigung
von Programmabläufen. Grundlegend ist die IF (wenn) dann ELSE (sonst) Anweisung. Man
kann auch nur die IF Anweisung (ohne ELSE) verwenden. In diesem Fall wird die folgende
Kommandozeile ausgeführt, wenn die Bedingung zutrifft. Verwendet man auch die ELSE
Anweisung, so wird entweder die nächste oder die auf ELSE folgende Kommandozeile
ausgeführt. Die Ausführung mehrer Anweisungen, wenn die Bedingung wahr ist, kann man
erreichen, indem man einen Block {} (geschweifte Klammern) setzt. IF Anweisungen lassen
sich auch verschachteln.
Einfache Vergleichsoperatoren sind:
==
!=
>
<
>=
<=
&&
||
gleich
ungleich
größer
kleiner
größer gleich
kleiner gleich
und
oder
Programm p4.java: if (- else) Abfrage
Aufgabe: Schreibe ein Programm welches eine Zufallszahl erzeugt, diese auf den Bildschirm
anzeigt und entscheidet, ob die Zufallszahl größer gleich oder kleiner ein Halb ist.
Algorithmus: Erzeugen einer Variable zur Speicherung der Zufallszahl. Ziehen der Zufallszahl.
Konditionale Abfrage ob diese >= 0.5 ist oder nicht. Dabei die Entscheidung ausgeben. Eine
Zufallszahl zwischen 0 und 1.0 erzeugen Sie mit der Methode Math.random();
Programmierung: Schreiben Sie das Programm p4.java in eine separate Datei mit einem
Texteditor. Lassen Sie die Kommentare weg. Beachten Sie bitte die Kommentare.
public class p4
{ public static void main (String args[])
{
double x;
x=Math.random(); //erzeuge eine Zufallszahl zwischen 0 und 1
System.out.println("X ="+x);
// konditionale Abfrage ob x < 0.5 ist
if (x<0.5) System.out.println("kleiner als 0.5");
//
if (x<=0.5) System.out.println("kleiner gleich 0.5");
else System.out.println("größer 0.5");
//
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 14 von 48
if (x>0.5)
{ System.out.println("größer als 0.5");
System.out.println("und noch eine extra Anweisung");
}
}
}
Aufgabe: Schreiben Sie ein Programm, welches die Sterbewahrscheinlichkeit eines Baumes über
einen Zufallseffekt steuert. Die Wahrscheinlichkeit, daß ein Baum im nächsten Zeitraum stirbt,
soll 5 % betragen. Rufen Sie das Programm 20 x auf und notieren Sie wieviele Bäume absterben.
Schleifen
Ein wichtiges Element in der Programmierung ist die Möglichkeit, Anweisungen wiederholt in
Schleifen auszuführen. In Java gibt es drei Schleifenanweisungen. Die Schleifen lassen sich
beliebig ineinander verschachteln, so kann man mehrdimensionale Probleme einfach bearbeiten.
Bei der while-Schleife wird eine Anweisung solange ausgeführt, wie ein bestimmter Ausdruck
am Schleifenanfang gilt.
Programm p5.java: while-Schleife
Aufgabe: Das Programm soll von einer zufälligen Variablen x mit einem Startwert zwischen 0
und 200 so oft 20 abziehen, solange x > 0 ist. Das Programm soll nach jeder Subtraktion den
Wert von x ausschreiben und am Ende die Anzahl der Subtraktionen mitteilen.
Algorithmus: 1.) Erzeugen einer Variablen x in der eine Zufallszahl zwischen 0 und 200
gespeichert wird. 2.) Erzeugen der Zufallszahl. 3.) Erzeugen einer Zählervariable n mit dem
Startwert 0. 4.) Verwenden einer while Schleife, in welcher 4.1) x um 20 subtrahiert wird. 4.2)
Ausgeben des Wertes von x. 4.3) Der Zähler n um 1 erhöht wird. 5.) Ausgabe der Anzahl der
Subtraktionen.
Programmierung: Schreiben Sie das Programm p5.java in eine separate Datei mit einem
Texteditor.
// while Schleife
public class p5
{ public static void main (String args[])
{
double x;
int n = 0;
// Erzeugen eine Zufallszahl zwischen 0 und 200
x=Math.random()*200.0;
System.out.println("Startwert von x = "+x);
while (x>=20.0)
{ x=x-20.0;
System.out.println("Wert von x = " +x);
n=n+1;
}
System.out.println("20 war "+n+" mal enthalten");
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 15 von 48
}ber
}
Die while-Schleife wird mit dem Wort while und einem nach folgendem konditionalen Abfrage
eingeleitet. Ist die Abfrage wahr oder true wie es in der Programmierung heißt, so werden die
Anweisungen, die sich im folgenden Block ({}) enthalten sind, ausgeführt. Andernfalls wird der
Anweisungsblock übersprungen. Bei der while-Schleife wird immer am Anfang die Bedingung
abgefragt.
Berechnen Sie für Stammstücke mit Längen von 30m, 29.8m, 17.5 m wieviel Rollen mit einer
Länge von 3,0 m Sie aus diesen Stammstücken schneiden können, wenn Sie ein Übermaß von 2%
in der Länge berücksichtigen müssen.
Die for-Schleife ist eine typische Zählerschleife, mit der sich Anweisungen n-Mal ausführen.
Die for-Schleife verfügt dazu über einen Zähler vom Typ Integer, der für einen definierten
Bereich durchgezählt wird.
Programm p6.java: for-Schleife
Aufgabe: Das Programm soll 10 mal die Zeile „Programmieren macht Spaß“ ausgeben.
Algorithmus: 1.) Erzeugen einer Schleife mit einem Zähler i und einem Bereich von 1 bis 20.
1.1) Ausgabe der Zeile „Programmieren macht Spaß“
Programmierung:
// for Schleife
public class p6
{ public static void main (String args[])
{
int i=1;
for (i=1;i<=20;i++) System.out.println("Programmieren macht Spass ");
}
}
Der Ausdruck in der Anweisung in der Schleife i++ ist gleichbedeutend mit i=i+1. Sie können
die Schreibweise alternativ verwenden. Es ist auch möglich den Schleifenzähler schneller z.B.
um 5 zu erhöhen (i=i+5), dann würde nur jeder 5. Schritt ausgeführt. Schleifenzähler können
auch rückwärts laufen.
Aufgabe : Ermitteln Sie 1) nummerisch das Alter des größten Höhenzuwachses für eine Winterlinde mit den
Startwerten Alter=5 und Höhe=20cm, 2) die Baumhöhe im Alter 100. Höhenwachstumsfunktion der Winterlinde:
γ 
ln 
alter
h
α = 1.011263, β = 0.495586, γ = 96.173358
ih =
β ⋅h
α
ih= Höhenzuwachs/a, h= Baumhöhe, alter=Alter; natürliche Logarithmus = Math.log(), Exponent = Math.exp()
Verwenden Sie dazu Jahresschritte von einem ganzen Jahr.
Literatur: Böckmann, Th. (1990): Wachstum und Ertrag der Winterlinde (Tilia cordata Mill) in Niedersachsen und
Nordhessen. Dissertation Univ. Göttingen. S.143; Sloboda, B. (1971): Zur Darstellung von Wachstumsprozessen mit
Hilfe von Differenzialgleichungen erster Ordnung. Mitt. Bad.-Württemb. Forstl. Vers. u. Forsch. Anst. 32
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 16 von 48
Bei der do ... while -Schleife wird am Ende der Schleife die Bedingung abgeprüft. Sie ist also
ähnlich wie die while-Schleife. Der Hauptunterschied ist der, dass die Schleife auf jeden Fall
einmal durchlaufen wird.
Programm p7.java: do ... while-Schleife
Aufgabe: Wir wollen einen Körper betrachten, der über eine Funktion aufgebaut und über eine
zweite gleichzeitig abgebaut wird. Der Startwert ist 50. Der Aufbauprozess hat eine Rate von
10/Alter. Der Abbauprozess von 2*Alter. Die Simulation startet im Alter 2. In welchem Alter
stirbt der Körper, wenn er mindestens einen Wert von 10 haben muss.
Algorithmus: 1.) Erzeugen einer Variable in der, der aktuelle Wert des Körpers gespeichert
wird. 2.) Erzeugen der Variable Alter. 3.) Beginn der while Schleife. 3.1) Berechnen des
Aufbaus 3.2) berechnen des Abbau 3.3) Alter+1 3.) konditionale Abfrage, ob Körper größer
Null. 4.) Ergebnisausgabe
Programmierung:
public class p7
{ public static void main (String args[])
{
double x=50; //Startwert des Körpers
int alter=2; // Alter
do
{ x=x+(10.0/alter);
x=x-(2.0*alter);
alter=alter+1;
}
while (x>=10.0);
System.out.println("Anzahl der Jahre "+alter);
}
}
Das Problem aus Programm p7 läßt sich auch mathematisch lösen. Wenn bei ähnlichen
Problemen jedoch Zufallseffekte enthalten sind, kann man solche Problem nur nummerisch
lösen.
Theoretisch benötigt man nur einen Schleifentyp. Mit den drei Typen kann man jedoch einige
Probleme leichter lösen und übersichtlicher schreiben.
Mit den Befehlen break und continue kann man zusätzlich Schleifen unterbrechen. Der break Befehl bewirkt, daß eine Schleife sofort unterbrochen und verlassen wird. Bei der continue
Anweisung wird der Rest des Schleifendurchlaufs nicht mehr abgearbeitet. Break und continue
sollte nur in Notfällen verwandt werden, die Anwendung dieser beiden Sprachelement gilt
allgemein als schlechter Programmierstil, daher finden Sie hier auch kein Beispiel.
Falls bei einer do oder while Schleife die Bedingung nie erreicht wird, hört das Programm nicht
auf zu rechnen. Sie können das Programm dann mit Gewalt unterbrechen, z.B. im DOS mit
Strg+C.
Mit der switch-Anweisung lassen sich Fälle unterschiedlich bearbeiten. Sie testet eine Integer-
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 17 von 48
Variable im Beispiel i, ob sie einer Konstanten entspricht. Die Konstante wird mit case
festgelegt. Die Bedingung wird durch einen : abgrenzt, auf den die spezielle Anweisung oder ein
Anweisungsblock folgt. Jede case-Anweisung muß mit einem break; abgeschlossen werden.
Programm p8.java: switch und break - Anweisung
Aufgabe: Wir wollen in einer Schleife von 1 bis 10 die switch Anweisung zeigen. Wenn der
Schleifenzähler 1 ist, soll Baumart 1 auf dem Schirm angezeigt werden, usw bis Baumart 3.
Zusätzlich soll bei jedem Schleifendurchlauf der Wert des Schleifenzählers auf dem Bildschirm
erscheinen.
Algorithmus: 1.) Erzeugen einer for-Schleife von 1 bis 3 wird. 1.1) Erzeugen der switch
Anweisung. 1.2) Ausschreiben des Wertes des Schleifenzählers.
Programmierung:
public class p8
{ public static void main (String args[])
{
for (int i=1;i<=10;i++)
{ switch (i)
{ case 1 : System.out.println("Baumart 1");break;
case 2 : {System.out.println("Baumart 2");} break;
case 3 : System.out.println("Baumart 3");break;
}
System.out.println("Durchlauf : "+i);
}
}
}
Aufgabe: Schreiben Sie mittels einer doppelten for-Schleife eine kleine Massentafel in
Tabellenform (Volumenberechnung mit Hilfe der einfachen Zylinderformel), wobei der BHD von
15 bis 20 cm die Zeilen definiert und die Höhe von 18 bis 22 m die Spalten bestimmt. Für die
Höhe und den Durchmesser sollen ganze Zahlen (Integer) verwendet werden.
Arrays
Zuvor haben wir gelernt, wie man Speichervariablen definieren und erzeugen kann. Stellen wir
uns vor, dass man in einem Programm z.B. auf die Durchmesser von 200 Bäumen jederzeit
zugreifen möchte, so wird die Definition der Variablen recht mühsam. In Java lassen sich, wie
mit fast allen Programmiersprachen dafür sogenannte Arrays oder Feldvariablen definieren. Mit
solchen Variablen kann man sehr einfach größere Datenmengen deklarieren und verarbeiten.
Eine Array-Variable muß man sich wie einen Vektor vorstellen. Diese Vektoren können auch
mehrdimensional sein. Array-Variablen werden immer mit eckigen Klammern []
gekennzeichnet. Den Speicherplatz für das Array selber muß man mit dem Schlüsselwort new
bereitstellen. Auf die einzelnen Variablen des Arrays kann man über den Index, der in der
eckigen Klammer (z.B. a[56]) angegeben wird, zugreifen.
double a[]; //Variable a ist eine Gleikomma-Arrayvariable
a = new double[1000]; //Damit stehen 1000 Variablen zur Verfügung
Beachten Sie, daß Arrays in Java mit dem Index 0 beginnen.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 18 von 48
Programm p9.java: Array-Variablen zur Berechnung des Mittelwerts
Aufgabe: Wir wollen 10 Durchmesserwerte zwischen 10 und 100 zufällig erzeugen und die
Werte in einem Array speichern. Von diesen 10 Werten wollen wir den Mittelwert berechnen.
Algorithmus: 1.) Erzeugen einer Zählervariable i 2.) Erzeugen eines Arrays mit 10
Speicherstellen vom Typ double. 3.) Erzeugen einer double Variable für den Durchmesser 4.)
Erzeugen einer Schleife von 0 bis 9 4.1) Erzeugen der Zufallswerte für den Durchmesser 5.)
Erzeugen einer neuen Schleife 5.1 Addieren der Durchmesserwerte 6. Berechnung des
Mittelwertes 7.) Ausschreiben des Ergebnisses
Programmierung:
public class p9
{ public static void main (String args[])
{
int i;
double bhd[]; // Definition der Array-Variable bhd
bhd= new double[10]; // Bereitstellen des Array für 10 Variablen
double dm=0.0;
for (i=0;i<=9;i++) //Achtung der Array beginnt beim Index 0
bhd[i]=10.0+Math.random()*90.0; //zufälliger BHD zwischen 10 und 100
for (i=0;i<=9;i++)
System.out.println("BHD "+(i+1)+" = "+bhd[i]);
for (i=0;i<=9;i++) dm=dm+bhd[i];
dm=dm/10;
System.out.println("Mittelwert : "+dm);
}
}
Mehrdimensionale Arrays lassen sich erzeugen durch die Anweisung:
double bhd[] [];
bhd= new double[10][10];
Übungsaufgabe: Schreiben Sie ein Programm, mit dem Sie 20 zufällige BHD-Werte sortieren
können. Berechnen Sie dann den D100 und den Dg. Es gilt, dass sich die 20 Bäume auf eine
Fläche von 0.1 ha beziehen. Hinweis: Die Quadratwurzel einer Zahl erhalten Sie mit der
Methode sqrt der Klasse Math ( 2.0=Math.sqrt(4.0) ). Mehr zu der Klasse Math ist später im
Text beschrieben.
Klassen
Zweck und Aufbau
Klassen sind spezielle Datentypen, die sich zum Einen aus Variablen mit verschiedenen
Datentypen (sogenannten Eigenschaften) und zum Anderen aus Methoden, die sich auf die
Klasse beziehen, zusammensetzen. Die Begriffe Klasse, Eigenschaft und Methoden kann man
sich verdeutlichen, in dem man z.B. einmal versucht einen Hund als Klasse für ein
Computerspiel abzubilden. So ein digitaler Hund hat verschiedene Eigenschaften, wie Größe,
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 19 von 48
Gewicht, Farbe, Zähne, Schwanz etc.. Damit der digitale Hund nun auch fressen, beißen, bellen
und mit dem Schwanz wedeln kann, hat er Methoden, die diese Vorgänge beschreiben. Hat man
so einen digitalen Hund und erst einmal erstellt, so kann man ihn beliebig vermehren, in dem
man viele Variablen oder einen Array der Klasse Hund erzeugt.
Im Unterschied zu den Arrays, besteht eine Klasse nicht nur aus dem gleichen Datentyp (z.B.
Integer), sondern die Eigenschaften können verschiedemste Datentypen sein. Die Klasse verfügt
zusätzlich über Methoden. Da Klassen selber Datentypen sind, kann man wiederum Variablen
dieser Klassen in anderen Klassen definieren. Diese Variablen heißen Instanzen einer Klasse
oder auch Objekte. Im Gegensatz zu den Programmiersprachen C und Pascal ist der
Programmierer nicht dafür verantwortlich, daß die Speicherbereiche, die durch Objekte belegt
werden, wieder freigegeben werden, weil im Hintergrund ein sogenannter Garbage collector den
Speicherplatz für die Objekte wieder frei gibt.
Eine Klasse besteht allgemein aus:
Modifizier class Klassenname extends Basisklasse implements Schnittstellen
{
Konstruktor
Eigenschaftendeklarationen
Methodendeklarationen
}
Der Modifizier ist optional, mit ihm läßt sich festlegen, ob eine Klasse z.B. public (öffentlich),
abstract oder final sein soll. Klassen, die als public gekennzeichnet werden, können überall
benutzt werden. Es kann in einer Quelldatei maximal eine Klasse public deklariert werden. Von
abstrakten Klassen kann kein Objekt erzeugt werden, sie dienen nur als Basisklasse für die
Vererbung. Von final gekennzeichneten Klassen können keine Subklassen abgeleitet werden.
Hinter dem Schlüsselwort class steht der Klassenname. Die Verwendung einer Basisklasse ist
optional. Mit ihr kann man der Klasse die Attribute und Methoden der Basisklasse vererben. So
kann ein Försterhund z.B. von der Klasse Hund abgeleitet werden und er kann mit zusätzlichen
Eigenschaften, wie „gehorcht auf Pfiff“ (ja/nein), und Methoden, wie „sucht_Wild“ oder
„läuft_weg“ versehen werden. Hund wäre in diesem Fall die Basisklasse. Die Methoden können
die Werte bzw. den Zustand von Eigenschaften ändern. Wenn der Hund, z.B. Wild sucht, verliert
er Gewicht. Schnittstellen steht für die Namen der Interfaces, deren Eigenschaften von der
Klasse realisiert werden.
Unter den Attributdeklarationen sind Variablen der Klasse zu verstehen. Methoden beschreiben
Funktionen. Jede Klasse verfügt automatisch über einen Standard-Konstruktor ohne Parameter.
Mit der Definition eines Kontruktors können bei der Erzeugung der Klasse zur Initialisierung
spezielle Aufgaben durchgeführt werden. Ein Konstruktor trägt den Namen der zugehörigen
Klasse und hat keinen Rückgabewert. Den Konstruktor muß man sich als eine Methode
vorstellen, die bei der Erzeugung der Klasse ausgeführt wird.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 20 von 48
Einfaches Klassenbeispiel
Wir definieren ein einfaches forstliches Objekt, einen Baum. Dieser Baum hat die Eigenschaften:
Art (Integer), Alter (Integer), Bhd (double), Hoehe (double). Vorerst wollen wir uns mit einer
Methode begnügen und definieren, daß der Baum mit einer Rate von 3% wächst. Man deklariert
den Baum:
Aufgabe: Wir schreiben eine Klasse Baum. Der Baum hat die Eigenschaften Art, Alter, BHD
und Höhe. Im Konstruktor sollen den Eigenschaften Startwerte zugewiesen werden. Die Klasse
Baum soll über eine Methode wachsen verfügen.
Programmierung:
class baum // Diese Klasse schreiben wir in die Datei baum.java
{ int alter;
String art;
double bhd, hoehe;
void baum() // Dies ist der Konstruktor
{ bhd=25.0;
hoehe=20.0;
alter=40;
art = "Buche"
}
void wachsen () //Methode wachsen
{ bhd = bhd*1.03;
alter= alter +1;
hoehe = hoehe*1.03
}
}
Man kann die Klassendefinition in dieselbe Datei oder in eine eigene Datei schreiben. Im
zweiten Fall muß die Datei aber denselben Namen wie die Klasse haben, in diesem Fall
baum.java. Achten Sie unbedingt auf die Gross- und Kleinschreibung; auch die muß
übereinstimmen. Die Klassendatei baum.class können Sie nicht mit Java starten, denn Sie
verfügt über keine Methode vom Typ main. Dafür kann man die Klasse baum in verschiedenen
Programmen nutzen. Im folgenden Programm p10.java wird die Klasse baum verwendet.
Aufgabe: Ein Baum der Klasse baum.class soll 10 Jahre lang wachsen. Wir wollen die
Veränderung von Alter, BHD und Höhe ausschreiben.
Programmierung:
Programm p10.java: Verwendung einer Klasse
public class p10
{ public static void main (String args[])
{
// Das Programm p10 hat keinen speziellen Konstruktor
// Definieren wir eine Variable Buche1 der Klasse baum
baum Buche1=new baum();
// Den Konstruktor aufrufen und die Startwerte setzen
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 21 von 48
Buche1.baum();
// Nun betrachten wir die Entwicklung während der nächsten 10 Jahre
for (int i=1;i<=9;i++)
{ Buche1.wachsen();
System.out.println("Alter "+Buche1.alter+" BHD "+Buche1.bhd+
" Hoehe "+Buche1.hoehe);
}
}
}
Ein neues Objekt der Klasse Baum mit dem Namen Buche1 erzeugt man mit der Anweisung.
baum Buche1=new baum();
Wenn Sie die Datei p10 starten, so muß java die Klasse Baum zur Verfügung stehen. Die Klasse
baum.class könnte auch in der Datei p10.java stehen. Da man die Klassen aber häufig auch in
anderen Programmen verwenden will, schreibt man die Klassen gewöhnlich in eigene Dateien.
Die Klassen müssen im selben Unterverzeichnis liegen, ansonsten muß man beim Starten des
Programms java die Option –cp (Classpath) setzen. Mehrfach genutzte Klassen können, wie z.B.
die mitgelieferten Klassen, in einer Bibliothek zusammengefaßt werden. Dazu muß man den
Pfad in der Systemvariablen Classpath definieren. Es gibt einige Java Programmieroberflächen
(z.B. Jbuilder von Borland oder Forte von Sun), die einem ganz wesentlich bei der Verwaltung
der Klassen helfen.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 22 von 48
Der Sinn der Klassen ist eine Bündelung von Daten und Methoden. Damit erhalten wir eine
bessere Ordnung. Die Klassen lassen sich in anderen Programmen oder Programmteilen
wiederverwenden. In Klassen kann man innere Vorgänge verstecken, wodurch die Klassen
besser zu warten sind, ohne daß im idealen Fall das Programm beeinflusst wird. Stellen wir uns
nur einmal vor, wir wollten die o.g. Routine, die das Wachstum beschreibt, begrenzen, damit die
Bäume nicht in den Himmel wachsen. Wir könnten das mit einer einzigen Änderung in der
Klasse baum.java erreichen. Diese Änderung würde sich dann in allen Programmen auswirken,
die auf die Klasse baum.class zugreifen.
Aufgabe: Schreiben Sie ein Programm, welches die Klasse Baum nutzt. Fügen Sie der Klasse
eine neue Methode zur Berechnung des Volumens hinzu (s. Volumenfunktion). Schreiben Sie
einen Baum (BHD=20cm, Alter=10, Art=211, Höhe=15m) über 20 Jahre fort und geben Sie die
Werte aller Variablen aus.
Durch Vererbung lassen sich Klassen erweitern und somit um neue Eigenschaften und
Methoden ergänzen. Denken wir uns, daß wir jetzt einen Nadel- und einen Laubbaum mit einer
Baumkrone benötigen. Beim Laubbaum wird die Krone durch eine Kugel und deren Radius
beschrieben. Die Krone des Nadelbaumes ergibt sich aus einem Kegel, der über die Kronenbreite
und den Kronenansatz definiert wird. In diesem Fall könnte man zwei neue Klassen Nbaum und
Lbaum definieren. Ein besserer Weg ist die Klasse baum zu verwenden und den Nadel- und
Laubbaum über Vererbung und Erweiterung zu definieren. Im nächsten Beispiel erweitern wir
die Klasse baum in eine Klasse baummk (mit Krone). Die Erweiterung wird mit dem
Schlüsselwort extends durchgeführt.
Programm p11.java: Anwendung und Erweiterung einer Klasse
Aufgabe: Die Klasse Baum verfügt über einige Eigenschaften und Methoden, diese sind aber für
unsere neue Aufgabe nicht ausreichend. Wir möchten, die Kronenbreite eines Baumes
mitbetrachten. Die Kronenbreite soll aus dem BHD abgeleitet werden (kb=1.388+0.18*BHD).
Man kann nun eine ganz neue Klasse schreiben, oder die alte Klasse baum verwenden und
erweitern. Wir wollen den zweiten Fall zeigen.
Programmierung:
// Erweitern der Klasse baum, diesmal
// in der gleichen Datei, wie das Hauptprogramm
class baummitkb extends baum
{
double kb ; //neue Variable für den Kronenbreite
// neue Methode zur Berechnung der Kronenbreite
void calculateKb()
{ kb=1.388+0.18*bhd;
}
// neue weitere Methode, die den Kronenradius ausgibt
double getKradius()
{ return kb/2.0;
}
}
public class p11
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 23 von 48
{ public static void main (String args[])
{
// Definieren wir eine Variable Buche 1
baummitkb Buche1=new baummitkb();
// Startwerte setzen
Buche1.baum();
Buche1.calculateKb();
System.out.println(Buche1.art+" BHD "+Buche1.bhd+" Kronenbreite "+Buche1.kb);
System.out.println(" Kronenradius "+Buche1.getKradius());
}
}
Wenn Sie die Klasse p11.java mit javac übersetzen, entstehen die zwei class baummitkb.class
und p11.class Dateien. Beide Dateien werden benötigt, um das Programm auszuführen.
Aufgabe: Erweitern Sie die Klasse baum um die Standpunktkoordinaten x, y und z eines Baumes
und zeigen Sie die Funktion in einem kleinen Beispiel.
Die nächste Anwendung zeigt, wie die Klasse baum in der Klasse wald als Array-Variable
verwendet wird. Zu beachten ist in diesem Fall, daß die Zeile baum ba[]=new baum[100]; nur
Zeiger zur Verfügung stellt. Der eigentliche Speicherplatz für die Array-Variable wird erst durch
die Zeile ba[nbaum]=new Baum(); bereitgestellt. Man sieht, daß das Programm mit den zwei
Klassen sehr klar gegliedert ist. Die Klasse baum behandelt die Operationen auf der
Einzelbaumebene, während die Klasse wald die Berechnungen auf der übergeordneten Ebene des
Waldes behandelt. Das Hauptprogramm stellt lediglich die Methoden zum Ansprechen der
beiden Klassen dar.
Programm p12.java: Verwendung zweier Klassen
Aufgabe: Wir wollen eine Eichenwald schaffen. Dazu wollen wir eine Klasse definieren, die eine
Eiche beschreibt und eine weitere Klasse die einen Wald mit Eichen beschreiben kann. Die
Objekte der Klasse Eiche sollen als Array in der Klasse Wald zur Verfügung stehen. Die Klasse
Eiche soll 3 Methoden haben: 1.) setStartwerte für Alter, BHD und Höhe. 2.) Eine Methode
wachsen. 3.) Eine Methode zur Volumenberechnung.
Die Klasse wald soll aus Objekten der Klasse eiche bestehen. Diese werden in einem Array
organisiert. Die Klasse Wald verfügt wiederum über 3 Methoden: 1.) addEiche um Eichen zum
Wald hinzuzufügen. 2.) Eine Methode wachsen, die alle Eichen des Waldes wachsen läßt. 3.)
Eine Methode um das Volumen aller Eichen abzufragen.
Im Hauptprogramm wird nun ein Wald erzeugt. Diesem Wald werden Eichen hinzugefügt. Die
Durchmesser- und Höhenwerte werden mit einer Zufallskomponente versehen. Zur Kontrolle
schreiben wir die Werte unserer Eichen aus. Dann lassen wir den Eichenwald 20 Jahre lang
wachsen und notieren jedesmal das Holzvolumen im Wald.
Programmierung:
class eiche
{
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 24 von 48
int alter;
double bhd,hoehe,volumen;
// Diese Methode setzt die Startwerte eines Baumes
void setStartwerte(int alt,double d, double h)
{
alter=alt;
bhd=d;
hoehe=h;
volumen=volumenNachFunktion(bhd,hoehe);
}
// Methode wachsen läßt die Eiche wachsen
void wachsen()
{
bhd=bhd*1.03;
hoehe=hoehe*1.05;
volumen=volumenNachFunktion(bhd,hoehe);
}
//
double volumenNachFunktion (double d,double h)
{
double pi=3.141592;
return pi*(d/200)*(d/200)*h*(0.4786-(1.0111/d)+(2.1042/h)-(203.2/(d*h*h)));
}
}
class wald
{
int nbaum=0; //Anzahl der Bäume
int i;
eiche ei[]=new eiche[100]; //Einzelbäume der KLasse Baum s.o
void addEiche(int alt, double d,double h)
{
ei[nbaum]=new eiche();
ei[nbaum].setStartwerte(alt,d,h);
nbaum=nbaum+1;
}
void wachsen()
{
for (i=0; i<nbaum; i++) ei[i].wachsen();
}
double gesamtVolumen()
{
double v;
v=0.0;
for (i=0; i<nbaum; i++) v=v+ei[i].volumen;
return v;
}
}
public class p12
{
public static void main (String args[])
{
wald w=new wald();
for (int i=0;i<10;i++)
{ w.addEiche(60,25+5.0*Math.random(),20+10.0*Math.random()); }
// nur zur Kontrolle
for (int i=0;i<w.nbaum;i++)
System.out.println(w.ei[i].alter+" "+w.ei[i].bhd+" "+w.ei[i].hoehe);
// lassen wir den Eichenwald mal wachsen
Jaff : Java für Förster 01.12.03
J. Nagel
for (int i=0; i<20; i++)
{
w.wachsen();
System.out.println("Volumen
}
Seite 25 von 48
: "+w.gesamtVolumen()); // Kommentar
}
}
Erweitern Sie die Klasse eiche durch Vererbung in eine Klasse meinEiche und fügen Sie als
zusätzliche Eigenschaften eine Wertvariable hinzu, die die Werte 1, 2, 3 und 4 annehmen kann.
Hüllklassen und Umwandeln von Datentypen
Für den Anfänger in Java ist es oft eine große Schwierigkeit, wenn er einen Datentyp in einen
anderen umwandeln muss. Stellen wir uns vor, wir lesen Daten als Zeichenkette (String) ein.
Nun wollen wir aber Teile einer solchen Zeichenkette als Zahl verwenden. Dazu müssen wir die
Zeichenkette in eine Zahl umwandeln. Dies klingt recht einfach, ist in Java aber z.T. etwas
verwirrend, da es für die primitiven Klassen (double) es sogenannte Hüllklassen gibt. Die
Hüllklassen verfügen über eine Anzahl von Methoden für den Zugriff auf die „umhüllende“
Variable. Mit diesen Methoden kann man z.B. Zeichenketten (Strings) in Integer oder
Gleitkommazahlen verwandeln.
Primitiver Datentyp
Hüllklasse
boolean
char
byte
short
int
long
float
double
Boolean
Character
Byte
Short
Integer
Long
Float
Double
So ist eine Variable vom Typ double der primitive Datentyp und nicht gleich dem Datentyp
Double, welcher die Hüllklasse ist. Man muß hier wie immer in Java auf die Groß- und
Kleinschreibung achten. Alle Hüllklassen haben die Methode toString(). Mit dieser Methode
kann man den Wert des Hüllobjektes als Zeichenkette ausgeben. Die numerischen Hüllobjekte
verfügen zu dem über die Methode valueOf(String s). Die Methode kann eine Zeichenkette in
den numerischen Datentyp umwandeln.
Programm p13.java: Verwendung zweier Klassen
Aufgabe: In dieser Anwendung soll die Umwandlung von Datentypen gezeigt werden.
Programmierung:
// Umwandlung von Datentypen
class p13
{
public static void main (String args[])
{
// Definition einiger Datentypen
double x = 55.5;
int n = 10;
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 26 von 48
String s1 = "88";
String s2 = "99.9";
// Umwandlung von x in ein int
int nvonx = (int) (x);
System.out.println("Umwandlung von double in int "+x+" "+nvonx);
// Umwandlung s1 in ein int
int nvons1 = Integer.parseInt(s1);
System.out.println("Umwandlung von String in int "+s1+" "+nvons1);
// Ein Test
System.out.println("Addition der neuen Integer "+(nvonx+nvons1));
// Umwandlung s2 in ein double
double dvons2 = Double.parseDouble(s2);
System.out.println("Umwandlung von String in double "+s2+" "+dvons2);
// Ein Test
System.out.println("Multiplikation von dvons2 mit 10.0 = " +(10.0*dvons2));
// Umwandlung double in eine Zeichenkette
String sneu = Double.toString(x);
sneu="Zeichenkette"+sneu;
System.out.println("Umwandlung von double in String "+sneu);
// Umwandlung int in eine Zeichenkette
String sneu2 = Integer.toString(n);
sneu2=sneu+sneu2;
System.out.println("Umwandlung von int in String "+sneu2);
}
}
Klasse Math
Ganz beiläufig hatten wir schon einige Methoden der Klasse Math kennengelernt. Diese
mitgelieferte Klasse enthält zahlreiche fertige mathematische Funktionen sowie die beiden
Konstanten E (Eulersche Zahl e) und PI die Kreiskonstante.
Methode
Erklärung
Typ abs(Typ x)
Typ min(Typ x, Typ y)
Typ max(Typ x, Typ y)
double ceil(double x)
double floor(double x)
int round(Typ x)
double sqrt(double x)
double pow(double x, double y)
double exp(double x)
double log(double x)
double sin(double x)
double cos(double x)
double asin(double x)
double acos(double x)
double tan(double x)
double atan(double x)
double random()
double PI()
Absolutbetrag von x. Typ steht für int, long, float, double
Minimum von x und y.
Maximum von x und y.
liefert die kleinste ganze Zahl > oder = x
liefert die größste ganze Zahl < oder = x
rundet auf eine ganze Zahl
Quadratwurzel von x
Potenz xy
ex
natürlicher Logarithmus von x
Sinus von x
Cosinus von x
Arcussinus von x
Arcuscosinus von x
Tangens von x
Arcustangens von x
Zufallszahl >=0 und <=1
Zahl PI
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 27 von 48
Klasse DecimalFormat
Die Klasse DecimalFormat aus java.text kann zur Darstellung und Umwandlung von
Dezimalzahlen verwendet werden. Mit DecimalFormat erzeugt man ein Objekt und übergibt
diesem ein bestimmtes Muster. Für das Muster können folgende Zeichen benutzt werden:
#
Ziffer, führende Nullen werden nicht ausgegeben
0
Ziffer, führende Nullen werden angezeigt
.
Decimalpunkt
,
Symbol für die Tausendertrennung
%
Darstellung als Prozentzahl
DecimalFormat f = new DecimalFormat(“##,##0.00“);
System.out.println(f.format(2101.879));
// Die Ausgabe wäre 2.101,88
Die Verwendung von DecimalFormat wird in dem Programm p16 gezeigt.
Aufgabe: Schreiben Sie eine Anwendung mit der Sie die Einzelbaumgrundfläche von zehn
zufällig erzeugten Bäumen (BHD zwischen 7 und 77cm) berechnen. Geben Sie das Ergebnis auf
eine Stelle hinter dem Komma in cm² aus.
Verwenden von Klassen aus dem Internet
Im Internet finden Sie zahlreiche Java Programme und java Klassen, die Sie für die Lösung Ihrer
Probleme verwenden können. Unter http://treegross.sourceforge.net wird von der
Niedersächsischen
Forstlichen
Versuchsanstalt
eine
Komponente
zur
Lösung
waldwachstumskundlicher Probleme bereitgestellt. Die Komponente treegross.jar (Tree Growth
Open Source Software) beinhaltet das komplette Waldwachstumsmodell BWINPro. Einige der
in treegross.jar enthaltenen Klassen, z.B. für die Volumenberechnung und die Ermittlung der
Schaftform, lassen sich auch einzelnd nutzen. Im folgenden wird die Klasse volumebynfv
vorgestellt. Diese Klasse enthält die gängigen Formzahl und Volumenfunktionen für
Niedersachsen.
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 28 von 48
Abbildung: Beschreibung der Klasse volumebynfv aus dem Packet treegross.jar im Netz durch Javadoc
Im Internet können wir eine Beschreibung zu der Klasse volumebynfv finden. Wichtig ist hier
die Erklärung des Konstruktors. Für ihn werden keine Übergabeparameter benötigt. In der
Methoden Summary finden wir die Methode volume. Diese liefert das Volumen eines Baumes
als double zurück, wenn der Baumartencode, der BHD und die Höhe übergeben werden. Den
Sourcecode der Klasse volumebynfv kann man sich auch aus dem Repository laden. Im Kopf für
die Klasse finden wir folgende Erklärung:
/** calculates the volume by volume or form function. Parameters: species code Lower Saxony,
if species code < 100 then the number is taken for the volume/form function; dbh [cm];
height [m]. The method returns the volume in cubic meters */
double volume(int spcode,double d,double h)
Mit anderen Worten können wir die Methode volume der Klasse volumebynfv nutzen, um das
Volumen eines Baumes zu berechnen. Im folgenden Beispiel wird die Verwendung der Klasse
volumebynfv deutlich.
Programm p13a.java: Verwendung einer Klasse
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 29 von 48
//Verwendung der Klasse volumebynfv zur Berechnung des Volumens
//
public class p13a
{ public static void main (String args[])
{
int baumartencode =211; // 211 ist der Code für Buche in Nds.
double bhd= 20.0; // Der Baum soll einen BHD von 20 cm haben
double hoehe= 19.5; // Der Baum soll eine Hoehe von 19,5m haben
double volumen =0.0; // in diese Variable soll der Volumenwert gespeichert werden
//
volumebynfv vnfv = new volumebynfv(); //Erzeugen des Objects volumebynfv
volumen=vnfv.volume(baumartencode,bhd,hoehe); // Aufruf der Methode volume
System.out.println("Das Volumen ist : "+volumen);
}
}
Wenn man das Programm p13a.java mit javac kompiliert, muss Datei volumebynfv.class im
gleichen Verzeichnis vorhanden sein. Befindet sie sich in einem anderen Verzeichnis, so muss
der classpath richtig gesetzt werden. Alternativ kann man auch die Datei treegross.jar
verwenden, die die Datei volumebynfv.class neben anderen enthält. Diese Datei muss ebenfalls
über den classpath zur Verfügung gestellt werden.
Aufgabe: Berechnen Sie die Länge und den Mittendurchmesser für ein Douglasienstammstück
(Baumartencode = 611), welches von einem Baum mit einem Durchmesser von 60 cm und einer
Höhe von 35m stammt. Das Stamm wurde in einer Höhe von 0,3m gefällt und soll in einem Stück
bis zu einem Zopfdurchmesser von 20cm ausgehalten werden. (Verwenden Sie als
Schaftformmodell die Klasse taperbysloboda aus dem treegross.jar, verwenden Sie die Methode
findd() und diameter()).
Lesen und Schreiben aus Dateien
Eine wichtige Funktion, die man beim Programmieren beherrschen muß, ist das Lesen und
Schreiben von Dateien. Erst dann kann das Programm in den meisten Fällen zu einem
wertvollen Werkzeug werden. Aber manchmal ist es auch schon genug, wenn man sich ein
kleines Programm schreiben kann, welches Daten, die in Spalten organisiert sind, in einer
anderen Reihenfolge ausgeben kann. In diesem Kapitel soll das einfache Schreiben und Lesen
aus Dateien erklärt werden. In den vorhergehenden Beispielen haben wir schon die Methode
println() der Klasse System.out kennengelernt.
Als erstes wollen wir aus einer Textdatei zeilenweisen lesen können. Die notwendigen Klassen
für den BufferedReader befinden sich in dem Paket java.io.*. Daher muß dieses zuvor mit
import angegeben werden. Mit import werden Klassen aus Paketen am Beginn der Datei dem
Programm bekannt gegben. BufferedReader verfügt über eine Methode in.readLine(), über
welche der String mit jeweils einer Zeile übergeben wird. Bitte versuchen Sie nicht alle
Einzelheiten des BufferedReader zu verstehen. Hier werden vordefinierte Klassen verwendet und
wenn man diese wie in dem Beispiel anwendet, kann man Datenzeilen lesen. Wichtig ist nur zu
wissen, dass wir dem Reader den Namen in gegegeben haben und wo wir den Dateinamen
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 30 von 48
testdat.txt anbringen können, damit wir aus einer bestimmten Datei lesen können. Das Lesen aus
einer Datei funktioniert nur, wenn wir auch das Abfangen von Fehlern zu lassen. Dafür gibt es
try {} und catch {}. Kommt es im Block von try zu einem Systemfehler, wie wenn z.B. die
Datei nicht exisiert, dann wird der Block catch ausgeführt. Die zulesende Datei muß im selben
Verzeichnis stehen, ansonsten muß das Verzeichnis mit dem Dateinamen angegeben werden.
Programm p14.java: Zeilenweises Lesen einer Textdatei
Aufgabe: Es sollen die Zeilen einer Textdatei zeilenweise gelesen werden.
Programmierung:
//Zeilenweise lesen aus einer Datei test.dat
import java.io.*;
public class p14
{ public static void main (String args[])
// Das Lesen aus Dateien benötigt try und catch für den
// Fall, dass es Fehler geben könnte
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 31 von 48
{ try
{
// Die folgenden 4 Zeilen sind noetig um einen FileInputStream zu erzeugen
// Die dafuer notwendigen Klassen stammen aus dem Paket java.io
// Sie sollten nicht zuviel über den Sinn der Zeilen zweifeln, wichtig ist
// das wir zeilenweise lesen koennen und wissen, wo wir den Dateinamen eingeben
BufferedReader in=
new BufferedReader(
new InputStreamReader(
new FileInputStream("testdat.txt")));
while (true)
{
// Einlesen einer Zeile in die Variable s
String s=in.readLine();
// wenn s keinen Wert hat ist das File zu Ende
if (s==null) break;
// ausschreiben von s
System.out.println(s);
}
}
// catch wird ausgelöst, wenn es einen Fehler unter try gibt
catch (Exception e)
{ System.out.println(e); //Ausschreiben der Fehlermeldung
}
}
}
Jetzt stellt man sich sicher die Frage, wie wir an unsere Zahlen, die wir zeilenweise eingelesen
haben, herankommen. Nun, dies ist ganz einfach. Man kann eine String-Variable in Teilstrings
oder Substrings zerlegen. Auch diese Funktion gibt es bei fast allen Programmiersprachen. Den
Teilstring kann man dann in eine Zahl verwandeln. Die Klasse String verfügt dazu über die
Funktion substring(n,m), wobei n und m Integer sind und die Position von und bis angeben.
Programm p15.java : Verarbeiten der eingelesenen Zeilen
Aufgabe: Der Durchmesser steht in unserer Datei testdat.txt auf der Spalte 7 bis 11. Diesen
wollen wir zeilenweise lesen und dann als Radius ausgeben.
Programmierung:
import java.io.*;
public class p15
{ public static void main (String args[])
{ double bhd=0.0;
String subs;
try
{ BufferedReader in=
new BufferedReader(
new InputStreamReader(
new FileInputStream("testdat.txt")));
while (true)
{ String s=in.readLine();
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 32 von 48
if (s==null) break;
// Schreiben der eingelesenen Zeile s
System.out.println(s);
// speichern des Teilstrings 7.bis 11. Zeichen nach subs
subs=s.substring(7,11);
System.out.println("Teilstring: "+subs);
// Umwandlung des Teilstrings ss in eine double-Variable
bhd=Double.parseDouble(subs);
double radius=bhd/2.0;
System.out.println("Radius : "+radius);
}
}
catch (Exception e)
{ System.out.println(e);
}
}
}
Aufgabe: Schreiben Sie ein analoges Programm, welches folgende Textzeilen aus einer Datei
lesen kann. Geben Sie dazu die Daten in eine Datei ein.:
Baumart, BHD, Höhe
Fi 20.0 28.0
Bu 22.0 32.0
Fi 24.0 32.0
Geben Sie die Mittelwerte von BHD und Höhe aus.
Nun möchten wir gerne unsere Daten wieder in eine Datei ausschreiben können. Im Prinzip ist
das nicht viel anders, als wir es bereits durch die Ausgabe auf die Kommandozeile gewohnt sind.
Dazu möchten wir die Variable BHD in einem besonderen Format ausgeben und zwar derart,
daß sie mit 3 Stellen hinter dem Komma angezeigt wird.
Zum Schreiben in ein Datenfile muß man zunächst einen OutputStream deklarieren. Diesen
OutputStream verbinden wir mit der Klasse PrintWriter. Die Klasse PrintWriter verfügt über
eine Funktion println() mit der man den Text in eine Datei über den OutputStream schreiben kann.
Am Ende des Programmes muß man dann noch die zum Schreiben geöffnete Datei geschlossen
werden. Dies geschieht mit der Funktion close() des PrintWriter. - Zahlen kann man in Java mit
der Klasse NumberFormat in ein bestimmtes Format umwandeln. Zunächst muß man sich ein
Objekt der Klasse NumberFormat deklarieren und über die Funktion getInstances() initialisieren.
Mit dieser Methode werden die Einstellungen von Windows bezüglich der Darstellung von
Zahlen übernommen. Mit den Funktionen setMaximumFractionDigits und setMinimumFractionDigits
läßt sich die minimale und die maximale Zahl der Nachkommastellen festlegen. Die Variable
BHD wird mit der Funktion format() der Klasse NumberFormat dann umgewandelt. Für die
Klasse NumberFormat müssen aber die Packete java.text.* und java.util.* vorher importiert werden.
Programm p16.java : Lesen und Schreiben einer Datei
Aufgabe: Wir lesen im nächsten Programm wieder den BHD ein. Diesmal wollen wir jedoch die
Grundfläche in eine weitere Datei namens ausgabe.txt schreiben. Dafür verwenden wir einen
OuputStream, den wir mit einem PrintWriter verknüpfen. Um die Ausgabe in ein Format zu
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 33 von 48
zwingen und so nur 3 Nachkommastellen angezeigt zu bekommen, benutzen wir die Klasse
number mit der Methode format. Vorher muss mit den Methoden setMaximumFractionDigits
und setMinimumFractionDigits noch die Anzahl der Nachkommastellen festgelegt werden.
Programmierung:
// Lesen und Schreiben von Dateien
import java.io.*;
import java.text.*;
import java.util.*;
public class p16
{ public static void main (String args[])
{ double bhd=0.0;
String subs;
NumberFormat number=NumberFormat.getInstance();
number=NumberFormat.getInstance(new Locale("en","US"));
try
{ BufferedReader in=
new BufferedReader(
new InputStreamReader(
new FileInputStream("testdat.txt")));
OutputStream os=new FileOutputStream("ausgabe.txt");
PrintWriter out= new PrintWriter(new OutputStreamWriter(os));
while (true)
{ String s=in.readLine();
if (s==null) break;
// Schreiben der eingelesenen Zeile s
System.out.println(s);
// speichern des Teilstrings 7.bis 11. Zeichen nach subs
subs=s.substring(7,11);
System.out.println("Teilstring: "+subs);
// Umwandlung des Teilstrings ss in eine double-Variable
bhd=Double.parseDouble(subs);
double g=Math.PI*Math.pow(bhd/200.0,2.0);
number.setMaximumFractionDigits(3);
number.setMinimumFractionDigits(3);
System.out.println("formatiert:"+number.format(bhd));
System.out.println("Grundflaeche in qm : "+number.format(g));
//Auschreiben des doppelten von BHD und ss
out.println(bhd+" "+g);
}
out.close();
}
catch (Exception e)
{ System.out.println(e);
}
in.close();
//
}
}
Aufgabe: Modifizieren Sie das Programm p16 so, daß neben dem Durchmesser auch die
Grundfläch des Baumes in cm² ausgegeben wird. Dazu benutzen Sie bitte die Methode Power der
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 34 von 48
Klasse Math. Die Grundfläche sollte mit einer Stelle hinter dem Komma ausgeschrieben werden.
Geben Sie den Text diesmal so aus, dass die Werte durch ein Semikolon getrennt werden.
Abschließend wollen wir uns noch einmal mit der Verarbeitung von Daten die in Textdateien
gespeichert sind beschäftigen. Bei fast allen Programmen gibt es eine Export Funktion, mit der
man sogenannten unformatierten Text schreiben kann. Ohne es Ihnen bewußt war, haben Sie
dies in der Übungsaufgabe gemacht, nämlich als Sie die Werte durch ein Trennzeichen von
einander getrennt haben. Auch aus z.B. Excel kann man solche Textdateien erstellen, in denen
die Werte nur durch ein Trennzeichen getrennt sind (Speichern unter *.csv). Diese Dateien kann
man übrigens auch importieren! Ein häufiges Problem ist dann aber, dass die Programme als
Dezimaltrennzeichen das Symbol verwenden, welches in der Ländereinstellung Ihres Rechners
angegeben ist. Sprich in Deutschland wir als Dezimaltrennzeichen das Komma verwendet, in
vielen anderen Ländern der Punkt. Bei der Erstellung von Programmen muss man dies beachten,
damit es nicht zu einem Absturz des Programmes kommt. Im folgenden wird daher ein kleines
Programm gezeigt, dem es egal ist, ob das Dezimalzeichen ein Komma oder ein Punkt ist. Es
werden einfach alle Kommatar in Punkte verwandelt. Darüber hinaus wird ein Verfahren gezeigt,
wie man die eingelesene Textzeile elegant zerlegen kann, ohne zuerst die Spaltenbreiten
abzählen zu müssen.
Programm p17.java : Ersetzen von einem Zeichen mittels eines Programms
Aufgabe: Wir lesen eine Datei test2.txt. In dieser sind Werte mittels eines Trennzeichen von
einander getrennt. Darüber hinaus wurde in der Datei als Dezimaltrennzeichen ein Komma
verwendet. Wir wollen diese Daten einlesen und auf den Bildschirm schreiben.
Programmierung:
// Lesen und Schreiben von Dateien
import java.io.*;
import java.util.*; //noetig fuer den StringTokenizer
public class p17
{
public static void main (String args[])
{
String art=""; double bhd=0.0;double h=0.0;int alter=0;
try
{
BufferedReader in=
new BufferedReader(
new InputStreamReader(
new FileInputStream("test2.txt")));
// Festlegen des Trennzeichens
StringTokenizer stx;
String delim=";" ;
while (true)
{
String s=in.readLine();
if (s==null) break;
// Hier werden alle Punkte des Strings durch ein Komma ersetzt
s=s.replace(',','.');
System.out.println(s);
stx= new StringTokenizer(s,delim);
art=stx.nextToken();
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 35 von 48
alter=Integer.parseInt(stx.nextToken());
bhd=Double.parseDouble(stx.nextToken());
h=Double.parseDouble(stx.nextToken());
System.out.println("Zerlegt "+art+" Alter "+alter+" BHD "+bhd+" H "+h);
}
System.out.println();
}
catch (Exception e)
{
System.out.println(e);
}
}
}
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 36 von 48
Die Klasse StringTokenizer stammt aus dem Paket java.util.* . Nachdem man die Zeichenkette
der Klasse StringTokenizer übergeben und das Trennzeichen festgelegt hat, kann man die
Zeichenketten zwischen den Trennzeichen komfortabel mit der Methode nextToken() erhalten.
Java API
In den vorher angeführten Beispielen haben wir bereits kennengelernt, daß die J2SE fertige
Klassen wie z.B. PrintWriter, Math und NumberFormat enthält. Für Java gibt es in Wirklichkeit
einige Hundert vordefinierte Klassen. Sie bilden das API (Application Programming Interface).
Die Klassen sind dabei in einzelnen Paketen zusammengefasst. Die Tabelle zeigt einige der
wichtigsten Pakete.
java.awt
java.beans
java.io
java.lang
java.math
java.net
java.rmi
java.security
abstract windowing toolkit. Es enthält die Klassen zur Grafikausgabe und zur Erzeugung von
Benutzeroberflächen.
Fertige Elemente zur graphischen Programmierung
Ein- und Ausgabe von Dateien, Netz und anderen Quellen.
Dieses Paket wird immer geladen und enthält string-Funktionen
unterstützt im Umgang mit langen Zahlen
Kommunikation über das Internet
Zugriff auf andere Rechner und von anderen Programmen
Verschlüsselung
Diese Klassen werden mit dem Import-Befehl dem Programm zugänglich gemacht. Beschrieben
sind die Klassen in der Dokumentation. Öffnen Sie dazu die Datei ...\docs\api\index.html. Sie
können diese Datei natürlich nur öffnen, wenn Sie die Dokumentation in diesen Bereich
installiert haben. Suchen Sie in dem Fenster unter all Classes in der alphabetischen Liste den
Begriff PrintWriter und klicken Sie ihn an. Nun erhalten Sie eine genauere Beschreibung dieser
Klasse. Wollen wir einen PrintWriter erstellen, so benötigen wir als Argument einen
OutputStream. Sehen wir uns den OutputStream an so wird uns dort mitgeteilt, daß es sich um
eine übergeordnete Klasse des FileOutputStreams handelt, welche als Argument einen String mit
dem Filenamen benötigt. Genau dies haben wir in beiden Befehlszeilen OutputStream os=new
FileOutputStream("ausgabe.txt"); und PrintWriter out= new PrintWriter(new OutputStreamWriter(os));
des Programms p16 erklärt. Unter PrintWriter werden dann auch die Funktionen println(), print()
und close() der Klasse PrintWriter beschrieben.
Grafik
Bisher haben wir die wichtigsten Programmierelemente kennengelernt, mit denen man forstliche
Probleme bearbeiten könnte. Aber die Programme sehen auf dem Bildschirm durch die reine
Textausgabe recht bescheiden aus. Moderne Programme verfügen über eine graphische
Oberfläche in Form von Fenstern bzw. eines GUI (Graphical User Interface). Die
Programmierung solcher Oberflächen wollen wir im Folgenden kennenlernen. Das Java Paket
AWT ermöglicht es uns, relativ einfach solche Oberflächen zu erzeugen und sie auf unsere
Bedürfnisse anzupassen. Es gibt noch ein zweites moderneres Paket, um Java Fenster zu
erzeugen, welches wir in einem späteren Projekt kennenlernen werden. Sie werden aber
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 37 von 48
feststellen, daß der Aufwand für die Programmierung der Oberfläche weit höher ist, als der den
Sie gewöhnlich für Ihre Berechnungen aufwenden müssen.
Programm p18.java : Einfache Definition eines Fensters
import java.awt.*;
public class p18
{ public static void main (String args[])
{ Frame fenster=new Frame();
fenster.setSize(300,300);
fenster.setVisible(true);
}
}
Im Programm p18 wird zuerst das AWT-Paket importiert. Danach definieren wir das Objekt
fenster der fertigen Klasse Frame(). Mit der Methode setSize läßt sich die Fenstergröße bestimmen,
in diesem Fall 300 mal 300 Bildpunkte. Für die Anzeige muß das Programm noch mit setVisible
sichtbar gemacht werden. Das Programm zeigt ein leeres Fenster, was sich aber nicht schließen
läßt. Dies kann man im Dos-Fenster nur durch gleichzeitige Eingabe der String und der C-Taste
erreichen. Das Dos-Fenster muß allerdings aktiv sein. Im weiteren Verlauf werden wir
kennenlernen, wie wir das Fenster über den Knopf schließen können.
Programm p19.java: Einfaches Fenster mit Text
import java.awt.*;
public class p19
{ public static void main (String args[])
{ Frame F=new Frame();
F.setSize(300,300);
F.setVisible(true);
Graphics g=F.getGraphics();
g.drawString("Eine Grafik",50,50);
}
}
Programm p19 zeigt eine leichte Erweiterung des Programmes. In diesem Fall wird auf der
graphischen Oberfläche der Text „Eine Grafik“ an der Position x=50 und y=50 ausgegeben.
Beachten Sie, das eine Position x=0 und y=0 auf einem graphischen Bildschirm immer die linke
obere Ecke meint. Insofern muß man die y-Koordinate immer erst transformieren. Dieses
Programm entspricht nun nicht der Idee, der objektorientierten Programmierung. Es könnte
nämlich passieren, daß die Methode drawString den Text zu einem Zeitpunkt schreiben will, an
dem unsere Klasse p19 noch nicht erzeugt ist.
Aufgabe: Positionieren Sie in einem Fenster (Pixelgröße 500x250), wie p19 einen Text in der
linken oberen Ecke und der unteren Hälfte.
Programm p20.java : Grafik mit Text, Linien und Kreis
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 38 von 48
/* JAFF = Java fuer Foerster
Ereignis orientierte Programmierung: Grafikfenster
*/
import java.awt.*;
class GFenster extends Frame
{
public void paint(Graphics g)
{
g.drawString("Waldsimulator",100,100);
Dimension d=getSize();
int w=d.width, h=d.height;
//Zeichnen zweier Linien
g.drawLine(0,0,w-1,h-1);
g.drawLine(0,h-1,w-1,0);
// Zeichnen eines Rechtecks
g.drawRect(0,0,w-1,h-1);
// Farbe einstellen
g.setColor(Color.red);
// Einen gefüllten Kreis in rot zeichnen
g.fillOval(w/2,h/2,30,30);
}
}
public class p20
{
public static void main (String args[])
{
Frame F=new GFenster();
F.setSize(500,500);
F.setVisible(true);
}
}
Im Fall von p20 wurde ein objektorientierter Ansatz gewählt. Zuerst wir die Klasse Frame zu der
Klasse GFenster erweitert. Wir definieren die Variable d vom Typ Dimension und können über die
Methode getSize() die Größe des Fensters erfragen. Anschließend werden 2 diagonale Linien mit
drawLine und ein Rechteck mit drawRect gezeichnet. Außerdem wird ein roter gefüllter Kreis in
der Nähe des Mittelpunktes gezeichnet. Die Klasse zum Zeichnen des Fensters wird im
Hauptprogramm aufgerufen und aktiviert. Vielleicht ist auch aufgefallen, das die Linien über das
ganze Fenster gemalt sind. Diesen Missstand wollen wir in den nächsten Programmen beheben.
Ansonsten regiert das Programm schon ganz gut auf die Veränderung der Fenstergröße. Alle
Elemente passen sich automatisch an.
Programm P21.java : Graphische Oberfläche mit Zeichenfläche, Label und Knopf
/* JAFF = Java fuer Foerster
Ereignis orientierte Programmierung: Grafikfenster
Zeichnen auf eine Leinwand, Überschrift und ein Knopf
*/
import java.awt.*;
class ZFlaeche extends Canvas
{
public void paint(Graphics g)
{
g.drawString("Waldsimulator",100,100);
Dimension d=getSize();
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 39 von 48
int w=d.width, h=d.height;
//Zeichnen zweier Linien
g.drawLine(0,0,w-1,h-1);
g.drawLine(0,h-1,w-1,0);
// Zeichnen eines Rechtecks
g.drawRect(0,0,w-1,h-1);
// Farbe einstellen
g.setColor(Color.red);
// Einen gefüllten Kreis in rot zeichnen
g.fillOval(w/2,h/2,30,30);
}
}
public class p21
{
public static void main (String args[])
{
Frame F=new GFenster();
F.setSize(500,500);
// Ein Label als Überschrift
F.add("North", new Label("Test Grafik"));
// Hier wird das Canvas in die Mitte des Fensters gesetzt
F.add("Center",new ZFlaeche());
// einen Knopf zum beenden unter die Grafik
F.add("South", new Button("beenden"));
F.setVisible(true);
}
}
Das Programm P21 zeigt, wie wir durch die Verwendung einer Zeichenfläche unsere Grafik auf
einen Teil des Fensters beschränken können. Gleichzeitig wurde das Fenster mit einem Label
und ein Knopf versehen. Der Knopf hat zwar noch keine Funktion, aber diese werden wir ihm
noch verleihen. Mit den Angaben North, South, East, West und Center kann man die Elemente
auf dem Fenster positionieren. Möchte man zwei Knöpfe z.B. unten anbringen, so sollte man ein
Panel verwenden und auf dieses zwei Knöpfe positionieren. Aufwendigere Designs erzielt man
über Tabellen, dazu verwendet man das GridLayout. Dies ist ähnlich wie bei HTML-Seiten. Der
Verzicht auf eine direkte Positionierung der Elemente hat aber den Vorteil, daß die Programme
auf Rechnern mit ganz unterschiedlicher Auflösung und Betriebssystemen trotzdem ansprechend
aussehen. Bei der Programmierung neigt man häufig dazu, ein spezielles Bildschirmdesign zu
entwerfen, was nur auf den eigenen Bildschirm zugeschnitten ist.
Programm p22.java : GUI mit Gridlayout
/* JAFF = Java fuer Foerster
Ereignis orientierte Programmierung: Grafikfenster
Zeichnen auf eine Leinwand, Überschrift und ein Knopf
*/
import java.awt.*;
class ZFlaeche extends Canvas
{
public void paint(Graphics g)
{
g.drawString("Waldsimulator",100,100);
Dimension d=getSize();
int w=d.width, h=d.height;
//Zeichnen zweier Linien
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 40 von 48
g.drawLine(0,0,w-1,h-1);
g.drawLine(0,h-1,w-1,0);
// Zeichnen eines Rechtecks
g.drawRect(0,0,w-1,h-1);
// Farbe einstellen
g.setColor(Color.red);
// Einen gefüllten Kreis in rot zeichnen
g.fillOval(w/2,h/2,30,30);
}
}
public class p22
{
public static void main (String args[])
{
Frame F=new GFenster();
//Die grafischen Elemente werden tabellenartig angeordnet
F.setLayout(new GridLayout(0,2));
//
F.setSize(500,500);
// Ein Label als Überschrift
F.add( new Label("Test Grafik"));
// Hier wird das Canvas in die Mitte des Fensters gesetzt
F.add(new ZFlaeche());
// einen Knopf zum beenden unter die Grafik
F.add( new Button("beenden"));
F.add( new Button("Knopf 2"));
// mit pack wird die Größe des Fensters abgestimmt
F.pack();
F.setVisible(true);
}
}
Variante p22 zeigt die Verwendung des GridLayouts, welche für diese Anwendung sicherlich
nicht am geeignesten ist, aber die Funktion GridLayout verdeutlicht. Mit dem Methode F.pack();
läßt sich die Fenstergröße auf die minimal nötige Größe für das Programm bestimmen.
Programm p23.java : GUI mit Knopf- Aktionen.
/* JAFF = Java fuer Foerster
Ereignis orientierte Programmierung: Grafikfenster
Schließen des Programms über einen Knopf
*/
import java.awt.*;
import java.awt.event.*;
class ZFlaeche extends Canvas
{
public void paint(Graphics g)
{
g.drawString("Waldsimulator",100,100);
Dimension d=getSize();
int w=d.width, h=d.height;
//Zeichnen zweier Linien
g.drawLine(0,0,w-1,h-1);
g.drawLine(0,h-1,w-1,0);
// Zeichnen eines Rechtecks
g.drawRect(0,0,w-1,h-1);
// Farbe einstellen
g.setColor(Color.red);
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 41 von 48
// Einen gefüllten Kreis in rot zeichnen
g.fillOval(w/2,h/2,30,30);
}
}
class schliessen implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
public class p23
{
public static void main (String args[])
{
Frame F=new GFenster();
F.setSize(500,500);
// Ein Label als Überschrift
F.add("North", new Label("Test Grafik"));
// Hier wird das Canvas in die Mitte des Fensters gesetzt
F.add("Center",new ZFlaeche());
// einen Knopf zum beenden unter die Grafik
Button b=new Button("beenden");
b.addActionListener(new schliessen());
F.add("South", b);
F.setVisible(true);
}
}
In Programm p23 wird nun endlich gezeigt, wie wir das Programm sauber wieder schließen
können. Dazu erzeugen wir uns zunächst die Variable b der Klasse Button. Diesem Knopf wird
nun mit b.addActionListener(new schliessen()) ein sogenannter ActionListener hinzugefügt, der als
Argument die Klasse mit der gewünschten Aktion enthält. In dieser Klasse schliessen() stehen die
nötigen Anweisungen, im speziellen Fall der Befehl System.exit(0);, der ein Programmende
bewirkt. Bei der Klassendeklaration ist es nötig, daß wir das Element implements ActionListener
hinzufügen.
Als letzte Übung wollen wir nun das Programm derartig schreiben, daß der rote Kreis über
Knopf gesteuert anfängt zu wachsen. Hierzu ist es nötig das Programm ein wenig zu verändern.
Programm p24.java : GUI mit Wachstum
import java.awt.*;
import java.awt.event.*;
class ZFlaeche extends Canvas implements MouseListener
{
private int x=-100,y=-100;
public ZFlaeche()
{
addMouseListener(this);
}
// Methode die die Grafik zeichnet
public void paint (Graphics g)
Jaff : Java für Förster 01.12.03
{
J. Nagel
g.drawRect(x-10,y-10,20,20);
g.drawString("Waldsimulator",100,100);
Dimension d=getSize();
int w=d.width, h=d.height;
//Zeichnen zweier Linien
g.drawLine(0,0,w-1,h-1);
g.drawLine(0,h-1,w-1,0);
// Zeichnen eines Rechtecks
g.drawRect(0,0,w-1,h-1);
// Farbe einstellen
g.setColor(Color.red);
// Einen gefüllten Kreis in rot zeichnen
Kreis k= new Kreis();
g.fillOval(w/2,h/2,k.hole(),k.hole());
}
// methode die die Maus beobachtet
public void mousePressed (MouseEvent e)
{
x=e.getX(); y=e.getY();
repaint();
}
//leere Methoden
public void mouseReleased (MouseEvent e) {
}
public void mouseEntered (MouseEvent e) {
}
public void mouseExited (MouseEvent e) {
}
public void mouseClicked (MouseEvent e) {
}
//neu Zeichnen
public void neuzeichnen()
{
repaint(); }
}
// Klasse zum Schließen des Fensters
class schliessen implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
//Klasse Kreis
class Kreis
{
static int radius = 20;
void wachsen()
{
radius=radius + 10;
}
int hole()
{
return radius;
}
}
// Klasse für das Fenster
class FensterFrame extends Frame implements ActionListener
{
ZFlaeche zf = new ZFlaeche();
public FensterFrame ()
{
super("Modell");
setSize(500,500);
setVisible(true);
// Ein Label als Überschrift
Seite 42 von 48
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 43 von 48
add("North", new Label("Test Grafik"));
// Hier wird das Canvas in die Mitte des Fensters gesetzt
add("Center",zf);
Panel Psued = new Panel();
// Knopf zum Wachsen
Button b1=new Button("Wachsen");
Psued.add("South", b1);
b1.addActionListener(this);
// einen Knopf zum beenden unter die Grafik
Button b2=new Button("beenden");
b2.addActionListener(new schliessen());
Psued.add("South", b2);
// Panel für die unteren Knöpfe
add("South",Psued);
//
F.repaint();
setVisible(true);
addWindowListener(
new WindowAdapter ()
{
public void windowClosing (WindowEvent e)
{
dispose(); System.exit(0);
}
}
);
}
public void actionPerformed (ActionEvent e)
{
Kreis k = new Kreis();
k.wachsen();
zf.neuzeichnen();
// Rabiater Schluss
}
}
public class p24
{
public static void main (String args[])
{
new FensterFrame();
}
}
In der Klasse p24 wird die Klasse aufgerufen, die das Arbeitsfenster definiert. Dieses
Arbeitsfenster, im Beispiel FensterFrame genannt, ist eine Erweiterung der Klasse Frame und
implementiert einen ActionListener. Zur Klasse Fensterframe werden die Elemente des
Arbeitsfenster, eine Zeichenfläche, eine Überschrift und zwei Knöpfe wie in den vorherigen
Beispielen hinzugefügt. Die Knöpfe werden beide mit einem ActionListener versehen. Über den
ersten Knopf wird die Klasse Schließen aufgerufen und ausgeführt. Der andere Knopf aktiviert
die Methode actionPerformed, die wiederum die Zuwachsmethode des Kreises aufruft und dafür
sorgt, daß die Methode neuzeichnen() der Klasse Zeichenflächen aufgerufen wird. Am Ende der
Klasse FensterFrame wird noch ein Windowslistener hinzugefügt, der es ermöglicht, daß man
das Fenster und Programm auch über den Knopf zum Schließen des Fensters beenden kann. –
Die Klasse Kreis definiert den Radius, der zu Anfang auf den Startwert von 20 gesetzt wird. Die
Klasse verfügt über die Methoden wachsen() und hole() zum Abfragen des Durchmessers. Die
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 44 von 48
Klasse Zflaeche implemiert einen MausListener mit dem wir Mausbewegungen auf der
Zeichenfläche abfragen können. Die Zeichnung wird mit der Methode neuzeichnen() ausgeführt.
Startet man das Programm und drückt auf den Knopf wachsen, so wird die Grafik mit der neuen
Kreisgröße gezeichnet.
In den vorherigen 24 kleinen Programmen, haben wir die wichtigsten Elemente der
Programmierung kennengelernt. Mit diesen wenigen Elementen, kann man fast alle wichtigen
Probleme lösen. Im folgenden Projekt Projekt1 wollen wir nun das zuvor besprochene
verwenden, um ein kleines und einfaches interaktives Wachstumsmodell zu erstellen.
Dokumentation mit javadoc
Die Entwicklungsumgebung von Java verfügt über ein einfaches Werkzeug mit man mehr oder
weniger automatisch sein Java Programm oder seine Java Klassen dokumentieren kann. Im Stil
der Java-Dokumentation werden durch den Aufruf von
C:\jaff\projekt1\javadoc –private *.java
unsere gesamten erstellten Klassen dokumentiert. Man kann die Dokumentation erheblich
verbessern, wenn man vor die Methoden und die Variablen der Klasse jeweils einen Kommentar
einfügt. Der Kommentar wird von Javadoc berücksichtigt, wenn er durch /** und */ abgegrenzt
wird. Erzeugen Sie die Dokumentation und sehen Sie sich das Ergebnis an, in dem Sie mit dem
Browser die Datei c:\jaff\projekt1\index.html aufrufen.
Weitergabe
Falls Sie ein Programm weitergeben wollen, müssen Sie zunächst entscheiden, wie Sie es
weitergeben wollen. Dazu ist grundsätzlich die Frage zu klären, soll derjenige den gesamten oder
Teile des Scource-Code erhalten und später in der Lage sein Änderungen selber zu machen, oder
möchten wir ihm das Programm nur in der Form geben, in der es zur Zeit exisiert und lassen
keinen Einblick in die Programmierung zu. Die Antwort zu dieser Frage hängt ganz von den
persönlichen Verhältnissen ab. Falls man von seinen Programmen leben möchte, wird man den
Scource-Code in der Regel nicht oder nur gegen die Bezahlung einer den Programmieraufwand
entsprechenden Summe mitliefern. Hat man den Programmcode erst einmal aus der Hand
gegeben, so können die Benutzer Änderungen machen und man hat keine Kontrolle mehr über
das Programm, z.B. ob das von einem selbst getestete Programme auf Grund von Veränderungen
mit einem Mal zu neuen Fehlern führt. Wie immer Sie sich nun entscheiden, ist letztlich Ihre
Sache. Will man dem Benutzer auch den Source Code komplett oder teilweise zur Verfügung
stellen, dann braucht man nur das Verzeichnis mit allen *.java und *.class Dateien dem Benutzer
weitergeben. Er kann sich von der Internetseite der Firma SUN entweder die Java
Entwicklungsumgebung oder falls er das Programm wirklich nicht verändern möchte die JavaRuntime Umgebung herunterladen und das Programm verwenden.
Im Fall, daß der Benutzer keinen Einblick in die Programmierung bekommen sollte, gibt man
nur die *.class Dateien weiter. Mit dem Befehl:
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 45 von 48
C:\einVerzeichnis\>jar -cf wwmodel.jar *.class
Kann man alle nötigen Class-Dateien in einer Datei zusammenfassen und komprimieren. In
diesem Fall muß man dem Benutzer neben den Daten nur die Datei wwmodel.jar weitergeben.
Testen Sie die Möglichkeit, in dem Sie die Datei wwModel.jar und die Daten Wald1.txt in ein
eigenes Verzeichnis kopieren und dort mit dem Befehl aufrufen:
C:\einVerzeichnis\>java –cp wwmodel.jar wwmodel
Diese Zeile kann man mit dem Notepad-Editor auch in einer Datei mit der Endung *.bat
speichern. Dann braucht der Benutzer unter Windows diese Datei nur doppelt anklicken.
C:\einVerzeichnis\> wwmodel.bat
Lösungen
Aufgabe a4 Massentafel:
public class a4
{ public static void main (String args[])
{
double vol =0.0;
int bhdvon=15;
int bhdbis=20;
// Massentafel
System.out.println(" M a s s e n t a f e l ");
System.out.println("
Hoehe ");
System.out.print("BHD ");
for (int j=12;j<18;j=j+2) {System.out.print(" "+j+" ");}
System.out.println();
for (int i=bhdvon;i<bhdbis;i=i+1)
{
System.out.print(" "+i+" ");
for (int j=18;j<24;j=j+2)
{
vol=0.4786-(1.0111/j)+(2.041/i)-(203.12/(i*j*j));
vol=Math.PI*(i/200.0)*(i/200.0)*j*vol;
vol=Math.round(vol*100.0)/100.0;
System.out.print(" "+vol+" ");
}
System.out.println();
}
}
}
Aufgabe a5 : Wachstum der Winterlinde
public class a5
{ public static void main (String args[])
{
int alter = 5; //setzen des Startalters
double hoehe =0.20 ; //setzen der Starthoehe
double ihmax =0.0 ; //speichern des max. Zuwachses
int alterihmax =0 ; // Alter des max. Hoehenzuwachses
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 46 von 48
double ih = 0.0; // Variable für den Hoehenzuwachs
for (int i=5;i<=100;i++)
{
ih=(0.495586*hoehe)/(Math.pow(alter,1.011263))*Math.log(96.173358/hoehe);
if (ih>ihmax)
{
ihmax=ih; //Hoehenzuwachs umspeichern
alterihmax=i; //Alter merken
}
if (i==100) System.out.println("Hoehe im Alter 100:"+hoehe);
hoehe = hoehe+ih; //Hoehe um den Hoehenzuwachs erhöhen
alter = alter+1;
}
System.out.println("Maximale Hoehenzuwachs: "+ihmax+" im Alter: "+alterihmax);
}
}
Aufgabe a6 : Sortieren Dg und D100
// Aufgabe: Schreiben Sie ein Programm, mit dem Sie 20 zufällige BHD-Werte sortieren können.
// Berechnen Sie dann den D100 und den Dg. Es gilt, dass sich die 20 Bäume auf eine Fläche
// von 0.1 ha beziehen. Hinweis: Die Quadratwurzel einer Zahl erhalten Sie mit der Methode
// sqrt der Klasse Math ( 2.0=Math.sqrt(4.0) ). Mehr zu der Klasse Math ist später im Text
// beschrieben
public class a6
{ public static void main (String args[])
{
double d[]; // Definition der Array-Variable bhd
d= new double[20]; // Bereitstellen des Array für 10 Variablen
// 20 BHD generieren
for (int i=0;i<20;i++) //Achtung der Array beginnt beim Index 0
d[i]=1.0+Math.random()*79.0; //zufälliger BHD zwischen 1.0 und ´80.0
// sortieren der 20 BHDs
for (int i=0;i<19;i++)
for (int j=i+1;j<20;j++)
if (d[i]<d[j])
{
double dmerk=d[i];
d[i]=d[j];
d[j]=dmerk;
}
// sortierte BHD zur Kontrolle ausschreiben
for (int i=0;i<20;i++) System.out.println(i+" BHD: "+d[i]);
// Kreisflächenmittelstamm berechnen
double dg=0.0;
for (int i=0;i<20;i++) dg=dg+Math.PI*(d[i]/200.0)*(d[i]/200.0);
dg= 200.0*Math.sqrt(dg/(20.0*Math.PI));
System.out.println("Kreisflächenmittelstamm: "+dg);
// Kreisflächenmittelstamm der 100 stärksten, hier 10 stärkste Bäume
double d100=0.0;
for (int i=0;i<10;i++) d100=d100+Math.PI*(d[i]/200.0)*(d[i]/200.0);
d100= 200.0*Math.sqrt(d100/(10.0*Math.PI));
System.out.println("D100
: "+d100);
Jaff : Java für Förster 01.12.03
}
}
J. Nagel
Seite 47 von 48
Jaff : Java für Förster 01.12.03
J. Nagel
Seite 48 von 48
Index
abstract 18
ActionListener 35
API 30
Arrays 16
AWT 30
Basisklasse 18
Block 9, 12
break 15
case 15
class 18
Classpath 6
Compiler 5
continue 15
Datentypen 11
do ... while -Schleife 15
Dokumentationskommtentar 9
ELSE 12
extends 20
Extension 6
Feldvariablen 16
final 18
for-Schleife 14
Frame 32
GUI 30
Hüllklassen 23
IF 12
import 25
Import 30
Instanzen 17
int 11
Integer 10
Interfaces 18
Interpreter 5
Klassen 17
Konstruktor 18
Lesen 25
Maschinensprache 5
Modifizier 18
Objekte 17
Operatoren 10
OutputStream 27
path 6
public 18
Schleifen 13
Schreiben 25
Substrings 26
switch 15
umwandeln 23
Vererbung 20
Vergleichsoperatoren 12
void 9
while-Schleife 13
Zeilenkommentar 9
Herunterladen