JAVA mit Netbeans

Werbung
JAVA mit Netbeans
Mag. Stefan Hagmann & Mag. Thomas Steiner
BG und BRG Frauengasse
Baden
Diese Dokument wird unter folgenden creative commons
veröffentlicht:
http://creativecommons.org/licenses/by-nc-sa/3.0/at/
Inhaltsverzeichnis
1.Einleitung, Voraussetzungen......................................................................................................... 4
2.Editoren IDE's............................................................................................................................... 4
2.1.Eclipse................................................................................................................................... 4
2.2.Die Netbeans Oberfläche.......................................................................................................5
3.Grundlagen................................................................................................................................... 5
3.1.Das erste Programm.............................................................................................................. 5
3.2.Starten des Programm's über die Konsole.............................................................................6
3.3.Die Struktur der Dateien........................................................................................................ 7
3.4.Klassen und Packages.......................................................................................................... 7
3.5.Variablentypen....................................................................................................................... 7
3.6.Konvertierung von Zahlentypen.............................................................................................9
3.7.String zu Zahlentyp ............................................................................................................... 9
4.Strukturen - Fallbeispiele............................................................................................................... 9
4.1.Operatoren............................................................................................................................. 9
4.2.If - Abfragen......................................................................................................................... 11
4.3.Switch – Anweisung............................................................................................................. 12
4.4.Schleifenarten...................................................................................................................... 13
4.5.Methoden – functions........................................................................................................... 15
4.6.Arrays.................................................................................................................................. 16
4.7.Dynamische Listen – Container...........................................................................................17
4.8.Strings................................................................................................................................. 18
4.9.Klasse StringBuilder.............................................................................................................22
4.10.DATE/CALENDAR- Arbeit mit Datum und Zeit...................................................................23
4.11.Exceptions......................................................................................................................... 24
4.12.Erstellen und Einbinden von Packages..............................................................................26
4.13.Formatierung der Systemstandardausgabe.......................................................................27
4.14.Einlesen der Tastatur.........................................................................................................29
4.15.Dateien und Streams.........................................................................................................29
5.Rekursion.................................................................................................................................... 31
5.1.Bespiel: Fibonacci Zahlen....................................................................................................32
5.2.Beispiel Quicksort................................................................................................................32
6.OOP – Objektorientiertes Programmieren...................................................................................34
6.1.Zugriffsmodifizierer..............................................................................................................37
6.2.Getter und Setter................................................................................................................. 38
JAVA mit Netbeans
Seite -1-
6.3.Konstruktoren...................................................................................................................... 38
6.4.Die static Methode ..............................................................................................................39
6.5.Mehrfachvererbungen - Interfaces.......................................................................................40
6.6.Verwendung der UML - Unified Modeling Language............................................................41
7.Fragen wir Dr. Java, Good to know.............................................................................................43
7.1.Bildschirmauflösung abfragen..............................................................................................43
7.2.Dynamisches Erstellen von Elementen................................................................................44
7.3.Warum erfolgt kein Repaint einer Komponente?..................................................................44
8.Threads mit Java......................................................................................................................... 44
8.1.Threads über das Interface Runnable..................................................................................44
8.2.wait() und notify()................................................................................................................. 45
8.3.Zugriff auf Daten aus einem Thread heraus.........................................................................46
8.4.Executors............................................................................................................................. 47
9.Grafische Anwendungen mit SWING...........................................................................................48
9.1.Mehrzeilige Labels............................................................................................................... 48
9.2.Actions und Events..............................................................................................................48
9.3.Mausereignisse erstellen.....................................................................................................49
9.4.Layout Manger..................................................................................................................... 50
9.5.Dialoge................................................................................................................................ 52
9.6.Die Sache mit den Pfaden, Icons, Images und Dateien.......................................................53
9.7.Die Sache mit dem JAR-File................................................................................................54
10.SWING Komponenten im Detail................................................................................................54
10.1.JTable Model...................................................................................................................... 54
10.2.Auf Ereignisse reagieren....................................................................................................55
10.3.Zellen darstellen un bearbeiten..........................................................................................55
10.4.Ein konkretes Beispiel .......................................................................................................56
10.5.Renderer und Editor in einer Klasse .................................................................................58
11.GDI............................................................................................................................................ 59
11.1.Zeichnen in einem Panel....................................................................................................59
11.2.Transformationen............................................................................................................... 59
11.3.Affine Transformation.........................................................................................................60
11.4.Punktierte Linie zeichnen...................................................................................................60
12.Erstellen von Java Applets für Webseiten..................................................................................60
12.1.Grundlagen........................................................................................................................ 61
12.2.Der HtmlConverter............................................................................................................. 61
12.3.Applets und jar-Dateien.....................................................................................................62
12.4.Erstellen und testen eines Applets.....................................................................................62
12.5.Testen des Projektes..........................................................................................................63
12.6.Automatischr Größenanpasseung des Applets an das Fenster.........................................64
13.Java Documentation erstellen...................................................................................................65
14.Virtual Machine steuern.............................................................................................................66
15.Netzwerkprogrammierung.........................................................................................................66
15.1.Datenpakete - TcpPackages..............................................................................................67
15.2.Paketarten......................................................................................................................... 67
16.SWING und Update von Komponenten.....................................................................................68
17.Zwischenablage und JAVA........................................................................................................ 69
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -2-
1. Einleitung, Voraussetzungen
Um Java programmieren zu können, braucht man einige Voraussetzungen am eigenen Computer
1. Java Runtime Umgebung
2. JDK, Java Development Kit
3. Netbeans als Editor
Jede Software ist über http://developers.sun.com/downloads/index.jsp zu beziehen.
Neben Netbeans kann man auch jeden anderen Editor verwenden. Erwähnt sei hier das Eclipse
http://www.eclipse.org/ Projekt.
Um ein Java-Programm auszuführen, benötigt man am Computer die JR (Java Runtime). Da es
die JR für alle Betriebssysteme gibt, kann man Java-Programme auf jedem BS ausführen.
2. Editoren IDE's
Im folgenden wird beschrieben, wie man die verschiedenen gängigen Editoren zum Arbeiten
bringt.
Netbeans arbeitet mit der SWING (SAF, swing application framework) Oberfläche, die momentan
(2010) nicht mehr weiterentwickelt wird. Eine Alternative wäre BSAF, better swing application
framework.
Eclipse hingegen, arbeitet mit der SWT Oberfläche.
2.1. Eclipse
Beachte: Das JDK muss bereist installiert sein.
Herunterladen von: http://www.eclipse.org/
Eclipse muss nicht installiert werden, einfach aus dem Ordner heraus starten. Bevor man startet
sollte man folgendes tun
1. Eclipse herunterladen und entpacken, die IDE for JAVA Developers reicht hier.
2. Deutsches Sprachpaket laden, vom Babel Projekt
http://www.eclipse.org/babel/downloads.php (hier findet man alle Sprachen). Suche dir dort
folgendes Paket BabelLanguagePack-eclipse-de_3...
Auch entpacken, und in den Ordner von Eclipse kopieren.
3. Um mit SWT arbeiten zu können, noch SWT herunterladen
von http://download.eclipse.org/eclipse/downloads/. Dort
das letzte Release auswählen, und SWT Binaries
herunterladen.
4. SWT (als zip File) Importieren mit Datei  Importieren 
Allgemein  Vorhandenes Projekt im Arbeitsbereich, dann
das Zip File Auswählen und Fertigstellen. Wir erhalten im
Projektbereich dieses Projekt, und können dmit arbeiten.
5.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -3-
2.2. Die Netbeans Oberfläche
Beachte: Das JDK muss bereist installiert sein.
Herunterladen von : http://netbeans.org/
Netbeans wird einfach installiert, und fertig.
Netbeans zeigt alle Projekte in einem
eigenen Fenster an. Hier kann man
die Projekte einsehen und
komfortabel verwalten. Links siehst
ein Beispiel, wie das aussehen kann.
Oft ist es hier verwirrend, wenn man
ein bereits bestehendes Projekt
importieren möchte.
Es ist nicht der Befehl Open Project.
Den verwendet man nur, wenn das
Projekt mit dem Befehl Close
geschlossen wurde (erkennbar am
). Wenn ein anderes Projekt aufgenommen werden soll, geht man wie
Icon Kaffeehäferl
folgt vor:
•
Neues Projekt
•
Java Project with existing Source
•
Dann die bestehenden Quellen des src Ordners angeben. Und dann wird das Projekt
importiert.
3. Grundlagen
3.1. Das erste Programm
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -4-
Der Haupteinstiegspunkt liegt in der Methode main. Dort lassen wir den üblichen ersten Text
ausgeben „Hallo Java“.
public class Main {
public static void main(String[] args) {
System.out.println("Hallo Java");
}
}
Mit dem Editor Netbeans drückt man nun die Taste F6 (Run Main Project) und sieht die Ausgabe
im unteren Teil des Programms.
3.2. Starten des Programm's über die Konsole
Manchmal möchte man ein Programm auch über die Konsole starten. Dazu muss man java.exe
aufrufen, das gelingt aber nur, wenn man den Pfad kennt.
Nehmen wir an, der Pfad zur java.exe liegt in C:\Program Files (x86)\Java\jre6\bin\.
Man kann nun in Windows den Pfad permanent setzen (Systemsteuereung, u.s.w.), oder man
erstellt sich ein Batch File, und setzt den Pfad bei Bedarf.
Im Batch File steht folgendes
@echo off
echo JAVA Console
echo Prepending 'C:\Program Files (x86)\Java\jre6\bin\' to PATH
PATH=C:\Program Files (x86)\Java\jre6\bin\;%PATH%
StartJavaConsole.bat
Dann legt man sich eine Verknüpfung an, die folgendes startet
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -5-
C:\Windows\System32\cmd.exe /k "StartJavaConsole.bat"
Wie man erkennen kann, wird zur Laufzeit der Pfad zur java.exe gesetzt, und ab jetzt kann man
sein Programm direkt starten.
3.3. Die Struktur der Dateien
Welche Verzeichnisstruktur mit welchen Dateien erhalte ich nun? Schauen wir uns dazu die
Verzeichnisstruktur genauer an.
Das erste Programm erzeugt nebenstehende Verzeichnisstruktur.
build: beinhaltet die *.class Dateien
src: beinhaltet die *.java Dateien
die anderen Ordner sind momentan nicht von Interesse für uns.
Die *.java Dateien sind die Quellcode Dateien, während die *.class Dateien die bereits
compilierten Dateien darstellen, die dann von der JR interpretiert werden.
Wird das Projekt mit build ausgeführt (F11), erhält man eine *.jar Datei. Das ist im Prinzip eine
zip-Datei in der alle *.class Dateien liegen. Starten kann man das Programm dann anschließend
mit java -jar Console1.jar. Für Windows gibt es einige Tools um aus *.jar Files *.exe Dateien
zu machen, z.B. JSmooth.
Ein Package hingegen beinhaltet viele *.java Dateien, und dient als eine Art Bibliothek. Packages
können beliebig oft von anderen Anwendungen verwendet werden.
3.4. Klassen und Packages
Packages beinhalten Sammlungen von Klassen. Will man solche Klassen in seinem Programm
verwenden, muss man diese mit dem import Befehl importieren.
Zum Beispiel die String Klasse beinhaltet alles, was zum Arbeiten mit Strings nötig ist. Diese
Klasse befindet sich im Package java.lang. Also importiert man diese Klasse mit
import java.lang.String;
Möchte man alles aus dem Package importieren, schreibt man einfach
import java.lang.*;
3.5. Variablentypen
Folgende Variablentypen haben wir in JAVA.
Type
Range
byte
-128 to +127
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Andere Typen
Type
Seite -6-
short
-32,768 to 32,767
int
-2,147,483,648 to 2,147,483,647
long
-9,223,372,036,854,775,808 to
9,223,372,036,854,775,807
Approximate range
-38
... +3.4 × 10
Precision
38
float
-3.4 × 10
7 digits
double
-1.7 × 10-308 ... +1.7 × 10308
15-16 digits
char
0 to 65535
Unicode Zeichen
bool
true oder false
Wie legt man nun Variable an, z.B. so
Variablentyp Name;
int x;
/*Variable nicht initialisiert*/
int x = 2; /*initialisiert*/
String was = "Hallo Welt";
Char x = 'C';
float fltValue = 0.123456789;
boolean myBool = true;
Für die Bezeichnung von Variablen muss man sich an gewisse Regeln halten. Ein Bezeichner in
Java kann beliebig lang sein und alle Stellen sind signifikant. Er muss mit einem UnicodeBuchstaben beginnen (d.h. 'A' bis 'Z', 'a' bis 'z', '_' und '$') und darf dann weitere Buchstaben und
Ziffern enthalten. Es können auch Buchstaben aus anderen Landessprachen enthalten sein,
allerdings darf es zu keinen Kollisionen mit reservierten Schlüsselwörtern kommen:
abstract
boolean
break
byte
case
catch
char
class
const
default
do
double
else
extends
final
finally
float
for
if
implements
import
instanceof
int
interface
long
native
new
private
protected
public
return
short
static
super
switch
synchronized
throw
throws
transient
try
void
volatile
while
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -7-
continue
goto
package
this
Die Literale true, false und null dürfen ebenfalls nicht als Bezeichner verwendet werden.
3.6. Konvertierung von Zahlentypen
Ein Standardproblem ist es, einen Zahlentyp in einen anderen über zuführen. Man kann hier
unterscheiden zwischen automatischer Konvertierung und expliziter Konvertierung.
int x = 4711;
double y;
y=x;
System.out.println(y);
Automatische Konvertierung int > double
int x,y;
short z;
x=10;
y=20;
z= (short)(x+y);
System.out.println(z);
Explizite Konvertierung int > short mit Hilfe des Type-Cast-Operators (siehe 4.1.2)
3.7. String zu Zahlentyp
Wie funktioniert das?
String zahl = "12.34";
double erg = Double.parseDouble(zahl) ;
Double ist ein ein Objekt und beherrscht verschiedenste Methoden die zu diesem Zahlentyp
passen. Beachte den unterschied zwischen double und Double!
4. Strukturen - Fallbeispiele
4.1. Operatoren
Math. Operatoren Aktion
+=
i += 10 entspricht i = i + 10
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -8-
-=
i -= 10 entspricht i = i – 10
+
Plus
-
Minus
*
Mal
/
Division
%
Modulo (berechnet Rest der Division)
++
i++ entspricht i=i+1
--
i-- entspricht i=i-1
Vergleichsoperatoren
==
Gleich
!=
Ungleich
>
Größer
<
Kleiner
>=
Größer oder gleich
<=
Kleiner oder gleich
Logische Operatoren
&&
UND (beide Ausdrücke müssen wahr sein)
||
ODER incl (mind. 1 Ausdruck muss wahr
sein)
^^
ODER excl (genau nur 1 Ausdruck darf wahr
sein)
bitweise Operatoren
<<
bitweises verschieben nach links
>>
bitweise Operatoren
Zuweisungsoperatoren
=
Einfache Zuweisung
+=
Additionszuweisung
-=
Subtraktionszuweisung
*=
Multiplikationszuweisung a*=b äquivalent mit
a= a*b
/=
Divisionszuweisung a/=b äquivalent mit a=
a/b
%=
Modulozuweisung
&=
UND-Zuweisung a&=b weist a den Wert a & b
zu
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
4.1.1.
Seite -9-
|=
ODER-Zuweisung
^=
Exklusiv-ODER- Zuweisung
<<=
Linksschiebezuweisung
?:-Operator
Der Fragezeichenoperator ist der einzige dreiwertige Operator in JAVA. Er erwartet einen
logischen Ausdruck und zwei weitere Ausdrücke, die beide entweder numerisch, von einem
Refereztyp oder vom Typ boolean sind.
Bei der Auswertung wird zunächst der Wert des logischen Operators ermittelt. Ist dieser wahr, so
wird der erste der beiden anderen Operatoren ausgewertet, sonst der zweite. Das Ergebnis des
Ausdrucks a ? b : c ist also b, falls a wahr ist und c, wenn a falsch ist.
Der Typ des Rückgabewerts entspricht dem Typ des größeren der beiden Ausdrücke b und c.
4.1.2.
Type-Cast-Operator
Mit disem Operator können explizite Typenumwandlungen (siehe 2.5.) vorgenommen werden. Er
findet primär dann Anwendung, wenn der Compiler keine impliziten Konvertierungen unterstützt,
z.B. bei der Zuweisung von größeren an kleiner numerische Typen oder der Umwandlung von
Objekttypen.
Der Ausdruck (type) a wandelt den Ausdruck a in einen Ausdruck vom Typ type um. Man sollte
allerdings beachten, dass das Ergebnis von (type) a ein Ausdruck ist, der nur auf der rechten
Seite des Zuweisungsoperators stehen darf, selbst wenn a z.B. eine Variable ist.
4.2. If - Abfragen
Dient dazu Fälle zu unterscheiden. Üblicherweise gibt es nur 2 Möglichkeiten
if (<Anweisung>){
…
}
else{
…
}
Wenn die Anweisung eintritt, wird der if Bereich ausgeführt. Tritt die Anweisung aber nicht ein,
der else Bereich.
Hier ein Beispiel
if (zahl1<zahl2){
System.out.println("Die Zahl {0} ist größer als die Zahl {1}",
zahl2, zahl1);
}
else{
System.out.println("Die Zahl {0} ist größer als die Zahl {1}",
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -10-
zahl1, zahl2);
}
Wie können Anweisungen aussehen, in etwa so
zahl1 == zahl2
zahl1 ist gleich zahl2?
zahl1 != zahl2
zahl1 verschieden zahl2?
zahl1 % zahl2 == 0
zahl1 modulo zahl2 gleich Null?
(x ==1 ) && (y != 1)
x gleich 1 UND y verschieden zu 1?
Ausdruck1 || Ausdruck2
Boolscher Ausdruck1 oder Ausdruck2
Es ist auch möglich, eine Kurzschreibweise zu schreiben
if (x<10){
y = 1;
}
else{
y = 0;
}
wird zu
y = x<10 ?1:0;
4.3. Switch – Anweisung
Die switch Anweisung ersetzt viele verschachtelte If Anweisungen. Die Syntax sieht wie folgt
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -11-
aus
switch (<Ausdruck>)
{
case <Konstante_1>
//Anweisungen
break;
case <Konstante_2>
//Anweisungen
break;
u.s.w
}
Als Beispiel wollen wir die Note eines Schülers abfragen
int Note = …;
switch (Note)
{
case 1:
System.out.println("Sehr gut");
break;
case 2:
System.out.println("Gut");
break;
case 3:
case 4:
case 5:
System.out.println("Auch nicht schlecht!");
break;
default:
System.out.println("Nix gefunden");
break;
}
Wie hättest du diese Abfrage mit if-Anweisungen erstellt? Überlege!
4.4. Schleifenarten
Schleifen sind ein wichtiges Instrument beim Programmieren. Sie haben die Aufgabe gewisse
Befehle solange zu wiederholen, bis ein Ziel erreicht worden ist. Welchen Schleifentyp man
verwendet ist an und für sich egal.
4.4.1.
For-Schleife
Die Syntax sieht wie folgt aus
for (Variable; Bedingung; Weiterschalten)
{
//Anweisungen
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -12-
}
Solange die Bedingung erfüllt ist, zählt die Schleife in der Variable mit Weiterschalten weiter.
for (int i=0; i<=101; i++)
{
System.out.println("Hallo das ist Satz Nr. "+ i);
}
Solange wie i kleiner oder gleich 101 ist, wird in Einserschritten i++ weiter gezählt und die
Anweisungen ausgeführt. Mit dem break Befehl kann man auch vorzeitig eine Schleife verlassen.
for (int i=0; i<=101; i++)
{
if (i==99)
{
break; /*Beenden der Schleife*/
}
System.out.println("Hallo das ist Satz Nr. "+ i);
}
4.4.2.
verbesserte for-Schleife, foreach
Diese Version erleichtert das Iterieren über alle Elemente in einem Array oder in anderen Arten von
Collections. Da diese Anwendung eigentlich die häufigste darstellt, erweist sie sich als äußerst
nützlich.
for(String name:arrayName)
{ // tu irgendwas
}
Die Stringvariable name dient hier als Iterationsvariable, in der die einzelnen Werte aus dem Array
für die weitere Verarbeitung im Anweisungsteil der Schleife aufgenommen werden. Die Elemente
des Arrays müssen mit dem Variablentypen von Name übereinstimmen. Bei jeder Iteration wird ein
neues Element aus dem Array aufgenommen. ArrayName steht für das Array oder die Collection,
die durchforstet werden soll.
4.4.3.
while - Schleife
Die Syntax sieht wie folgt aus
while (<Bedingung>)
{
//Anweisungen
}
Schauen wir uns dieses Beispiel an
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -13-
int intVar = 0;
while (intVar < 5)
{
intVar++;
if (intVar == 3) break;
System.out.println(intVar);
}
Wie man sehen kann, muss außerhalb der Schleife eine Zählvariable intVar definiert werden.
Innerhalb der Schleife muss man diese Variable weiter zählen. Gerne vergisst man das, und
erzeugt damit ungewollt eine Endlosschleife.
4.4.4.
break
Mit break kann man eine Schleife (for, while,do aber auch switch) vorzeitig verlassen.
for(int i = 0; i < a.length; i++) {
if (a[i] == 0)
break;
}
Mit break ist es auch möglich, die Ausführung nach dem Abbruch hinter einem übergeordneten
Programmblock fortzusetzen. Hierzu muss dem betreffenden Programmblock eine Marke
vorangestellt werden, die dann bei der break-Anweisung angegeben wird.
demo: { index = 0;
while(index < a.length) {
if (a[index++] == -1)
break demo;
}
// Stelle 1
}
// Stelle 2
4.5. Methoden – functions
Wichtig ist die Unterscheidung ob Methoden mit oder ohne Rückgabewert erstellt werden. Eine
explizite Unterscheidung ist hier nötig.
/**
* Eine öffentliche Methode ohne Rückgabewert
*/
public void Meinefunktion(){
}
Wenn kein Rückgabewert existiert, schreibt man das Schlüsselwort void!
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -14-
/**
* Eine private Methode
* @return die Zahl 12
*/
private int Meinefunktion2(){
return 12;
}
Mit einem Rückgabewert muss der Typ des Wertes angeschrieben werden, hier int also Integer.
4.6. Arrays
Werden wie in php folgendermaßen definiert, Typ[] Name.
int[] chessboard;
Point[][] points;
Mit Inhalten befüllt wird ein Array so
int[] prim = { 1, 2, 3, 5, 7, 7 + 4, };
String[] nouns = {
"Haus", "Maus",
"dog".toUpperCase(),
/*DOG*/
new java.awt.Point().toString()
};
Zugriffe geschehen über eine Indexnummer
int[] zahlen = { 1, 2, 3, 5, 7, 7 + 4, };
System.out.println( zahlen.length );
System.out.println( zahlen[0]);
System.out.println( zahlen[3]);
Arrays mit bestimmter Länge erzeugen
int[] zahlen = new int[100];
//erzeugt ein Array, das mit 100 Stellen, die jeweils mit dem
Integer 0 initialisiert werden
Auch mehrdimensionale Arrays sind Standard wie folgendes Beispiel zeigt
zahlen[3][0] = 1;
zahlen[1][3] = 4;
Wobei es hierbei im Gegensatz zu vielen Programmiersprachen auch möglich ist, nichtrechteckige
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -15-
Arrays zu erzeugen. Dies liegt daran, dass mehrdimensionale Arrays als verschachtelte Arrays
gespeichert werden.
/*Beispiel für ein dreieckiges Array*/
int[][]a ={{0},
{1,2},
{3,4,5},
{6,7,8,9}};
4.7. Dynamische Listen – Container
Da man oft nicht weiß wie viele Elemente gespeichert werden sollen, sind Arrays hier ein Problem.
Bei dynamischen Listen können jeder Zeit Elemente gespeichert und gelöscht werden. Die Anzahl
der Elemente muss nicht beachtet werden.
Schauen wir uns ein Beispiel an
import java.util.*;
public static void main( String[] args )
{
Collection c = new LinkedList<Integer>();
for ( int i = 0; i < 5; i++ )
c.add( "" + i );
System.out.println( c );
}
Der Typ Collection erlaubt es beliebig viele Elemente zu speichern.
Es stehen auch einige Methoden zur Verfügung:
Methoden für ArrayLists
add(Object elem)
Fügt der Liste das Object elem hinzu
remove(int index)
Entfernt das Objekt mit dem angegebenen
Index
remove(Object elem)
Entfernt dieses Objekt, falls vorhanden
contains(Object elem)
Liefert true falls vorhanden
isEmpty()
Liefert true, falls die Liste keine Elemente
enthält
indexOf(Object elem)
Liefert den Index des Elements oder -1
size()
Liefert die Anzahl der Elemente
get(int index)
Liefert das Object mit angegebenem Index
Zu keiner Zeit braucht man sich Gedanke über die Anzahl der Element Gedanken machen. Die
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -16-
Syntax
Collection c = new LinkedList<Integer>();
oder
LinkedList<Double> koord = new LinkedList<Double>();
gibt an, das ausschließlich Integer Typen in der Collection gespeichert werden.
Als Containerklassen für Collections kommen die ArrayList und die LinkedList in Frage.
Der Zugriff auf eine ArrayList ist schneller, während alle Elemente in der LinkedList
untereinander verkettet sind, was das Behandeln der Reihenfolge einfacher macht. Weiters gibt es
das HashSet, TreeSet, LinkedHashSet, HashMap, TreeMap, LinkedHashMap, WeakHashMap,
LinkedList, ArrayBlockingQueue und PriorityQueue. Bitte hier in der Dokumentation
nachlesen!
4.8. Strings
Wie schon vorhin erwähnt benötigt man zum Arbeiten mit Strings die entsprechende Klasse aus
dem java.lang-Package.
Eine neue Stringvariable deklariert man nun folgendermaßen:
String test = new String();
//eine leere Zeichenkette wird erzeugt;
Man kann nun diese Variable auch gleich mit einer Zeichenkette initialisieren:
String s = new String("Heute ist ein schöner Tag!");
4.8.1.
Initialisierung durch char-Arrays
Zur Klasse String gibt es einen Konstruktor, der die Inhalte eines Arrays in eine Zeichenkette
überträgt:
char text[] = {'I','n','f','o','r','m','a','t','i','k'};
String s = new String(text);
Durch die Angabe des Index und der Anzahl der Zeichen werden die Zeichen teilweise aus dem
Array übernommen:
char text[] = {'I','n','f','o','r','m','a','t','i','k'};
String s = new String(text,2,4);
System.out.println(s);
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -17-
Als Ausgabe erhalten wir erwartungsgemäß „form“.
4.8.2.
Stringmethoden
Die Klasse String liefert einige Methoden, die den Umgang mit Strings erleichtern.
Um die Länge einer Zeichenkette zu ermitteln:
String s = new String("Heute ist ein schöner Tag!");
System.out.println(s.length());
Um ein Zeichen an einer bestimmten Stelle auszugeben:
System.out.print(s.charAt(5));
Weitere wichtige Methoden:
Stringmethoden
getChars()
Auswahl einer zusammenhängenden
Zeichenkette mit Startindex bis Endindex wird
in eine Array geschrieben, beginnend mit
dem Index start_ergebnis
getChars(int start, int ende, char
ergebnis[], int start_ergebnis)
4.8.3.
indexOf()
Liefert die Position des ersten Auftretens des
angegebenen Zeichens (bzw. Zeichenkette)
substring()
Liefert eine Teilzeichenkette mit Startindex
und Endindex
replace()
Ersetzt in einer Zeichenkette ein bestimmtes
Zeichen durch ein anderes
replace( char alt, char neu)
trim()
Entfernt vorangehende und anschließende
nicht druckbare Zeichen
Operatoren für Zeichenketten
Man kann mehrere Zeichenketten mit Hilfe von concat() verketten:
String s1 = new String("BRG");
String s2 = new String("Frauengasse");
System.out.println(s1.concat(s2).concat("!"));
Um Zeichenketten und Variablenwerte nebeneinander zu verwenden, verkettet man diese mit „+“:
int a = 10;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -18-
int b = 20;
System.out.println(a + " + " + b + " = " + a + b);
System.out.println(a + " + " + b + " = " + (a + b));
Man beachte die unterschiedlichen Ausgaben. Um vor der Verkettung Berechnungen auszuführen
(wie hier z.B. a+b ), muss man Klammern verwenden, da sonst das „+“ als Verkettungsoperator
interpretiert wird.
Man kann 2 Zeichenketten mit Hilfe der Methode equals() auf Gleichheit überprüfen. Die
Ausgabe liefert Boolesche Werte.
String s = new String("hallo");
System.out.println(s.equals("hallo"));
Sonstige Vergleichsmethoden
equalsIgnoreCase()
Beim Vergleichen wird Groß/Kleinschreibung
igoriert
startsWith()
Überprüft ob ein String mit einer bestimmten
Zeichenkette beginnt
endsWith()
Überprüft ob ein String mit einer bestimmten
Zeichenkette endet
(Ergebnis:Boolescher Wert)
compareTo()
Überprüft neben der Gleichheit der
Zeichenketten die alphabetische
Abhängigkeiten (vgl. Wörterbuch). Das
Ergebnis ist eine ganze Zahl: Steht die
aufrufende Zeichenfolge im Wörterbuch vor
der angegebenen, so liefert compareTo() eine
negative Zahl; bei Gleichheit Null. Steht die
aufrufende Zeichenkette im Wörterbuch nach
der angegebenen, so ist das Ergebnis eine
positive Zahl.
regionMatches()
Vergleicht zwei gleich lange String-Regionen,
die in zwei unterschiedlichen Strings an zwei
unterschiedlichen Positionen liegen können
auf Gleichheit
Syntax: regionMatches(int <Position
1. Zeichenkette>, String<2.
Zeichenkette>, int <Position 2.
Zeichenkette>, int <Länge der
Region>)
Wenn die Groß- und Kleinschreibung ignoriert
werden soll, wird als zusätzlicher Parameter
an erster Stelle ignoreCase hinzugefügt.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -19-
Kleines Beispiel zu compareTo() :
String s = new String("hallo");
System.out.println("hallo: " + s.compareTo("hallo"));
System.out.println("ha: " + s.compareTo("ha"));
System.out.println("Hallo: " + s.compareTo("Hallo"));
System.out.println("abc: " + s.compareTo("abc"));
System.out.println("hallo - ist da jemand: " + s.compareTo("hallo ist da jemand"));
System.out.println("huch: " + s.compareTo("huch"));
liefert folgende Ausgabe:
hallo: 0
ha: 3
Hallo: 32
abc: 7
hallo - ist da jemand: -16
huch: -20
Kleines Beispiel zu regionMatches():
System.out.println(„Grüße aus Baden“.regionMatches(8,“Greetings
from Austria“,8,2);
//Vergleicht, ob eine Region der Länge 2 jeweils an der Position 8
der beiden Strings ident ist und liefert in diesem Falle „true“
4.8.4.
Anwendungsbeispiel „BUBBLESORT“
String satz[] = {"informatik", "ist", "schön", "und", "lehrer",
"lügen", "nicht"};
for (int i = 0; i < satz.length; i++) {
for (int j = i+1; j < satz.length; j++) {
if (satz[j].compareTo(satz[i]) < 0) {
String wort = satz[i];
satz[i] = satz[j];
satz[j] = wort;
}
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -20-
System.out.println(satz[i]);
}
4.9. Klasse StringBuilder
Ebenso wie bei Arrays kann man an Strings grundsätzlich keine zusätzlichen Zeichen anhängen
oder auch nur die zumindest die Länge verändern. Zu diesem Zwecke hat man zwei Klassen
implementiert: StringBuffer und StringBuilder. Da StringBuilder als neuere die
ressourcenschonendere und schneller Klasse darstellt, werden wir uns vorerst einmal auf diese
Klasse beschränken, wobei ja beide Klassen soundso dieselben Methoden besitzen.
Ein leerer StringBuilder wird erzeugt mit StringBuilder(). Wird ein String übergeben, so wird
ein StringBuilder-Objekt erzeugt, das eine Kopie der übergebenen Zeichenkette enthält
(StringBuilder(String a) ).
4.9.1.
Methoden
Methoden der StingBuilder-Klasse
append(String s)
String s wird am Ende des Objektes
angehängt
insert (int offset,
Sting s)
An der Position offset wird String s in
das Objekt eingefügt
deleteCharAt(int
index)
Einzelnes Zeichen wird an der Position
index gelöscht wird
delete(int start, int
end)
Entfernt einen Teilstring
setCharAt(int index, Ersetzt ein Zeichen an angegebener Position
char c)
replace(int start, int
end, String str)
4.9.2.
length()
Länge
capacity()
Wert des belegten Pufferspeichers
Konvertierung in einen String
Wenn man mit der Manipulation der Zeichenkette fertig ist, kann man ein StringBuilder-Objekt
wieder in einen String verwandeln. Mit der Methode String toString() kann man dies
effizient machen, wobei erst bei erneuter Veränderung des StringBuilder-Objektes eine Kopie der
Zeichenkette erstellt wird. Ansonsten wird nur ein Zeiger auf den Zeichenspeicher gelegt, was
Ressourcen spart.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -21-
4.10. DATE/CALENDAR- Arbeit mit Datum und Zeit
Wenn man einen Zeitstempel benötigt, verwendet man die date-Klasse (java.util.Date). Es dient
eigentlich zum Speichern eines Datum-/Zeitwertes (als 64-Bit-Long-Variable) in ms (Millisekunden)
seit 1970-01-01 0h UTC (negative Werte sind vor 1970).
// Aktuelles Datum:
import java.util.*;
Date dt = new Date();
System.out.println( "Date = " + dt );
// z.B. 'Fri Jan 26 19:03:56 GMT+01:00 2001'
System.out.println( "ms = " + dt.getTime() );
// z.B. '980532236731'
Das Calendar-Objekt verwendet man für Berechnungen mit Datums- und Zeitwerten.
// Verschiedene Verfahren zur Erzeugung eines Kalender-Objekts:
import java.util.*;
Calendar myCal1 = Calendar.getInstance();
// lokales Kalendersystem mit aktueller Zeit
Calendar myCal2 = new GregorianCalendar();
// GregorianCalendar mit aktueller Zeit
Calendar myCal3 = new GregorianCalendar(1956,Calendar.MARCH,17);
// GregorianCalendar mit vorgegebener Zeit
// Setzen von Jahr + Monat + Tag:
myCal2.set( 1956, Calendar.MARCH, 17 );
// ändert so nicht Stunden, Minuten und Sekunden
myCal2.setTime( myCal2.getTime() );
// nicht mehr unbedingt notwendig seit JDK 1.2
// Zeit setzen mit Date:
myCal2.setTime( new Date() );
// Einzelne Felder extrahieren:
int year = myCal2.get( Calendar.YEAR
);
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -22-
int mnth = myCal2.get( Calendar.MONTH ) + 1;
// nicht vergessen die 1 zu addieren
int date = myCal2.get( Calendar.DATE
);
System.out.println( date + "." + mnth + "." + year );
Formatierung ist SimpleDateFormat besser
// für
SimpleDateFormat format = new SimpleDateFormat("yyyy:MM:dd
HH:mm:ss");
datum = format.parse(dstr);
// Calendar ist gut geeignet, um Berechnungen durchzuführen,
// z.B. um den um ein Jahr erhöhten Zeitwert zu berechnen:
myCal2.add( Calendar.YEAR, 1 );
// Umwandlung von Calendar in Date:
Date myDate = myCal2.getTime();
System.out.println( myDate );
Methoden der Calendar-Klasse
set
Um die Zeit auf einen bestimmten Wert zu
setzen Beispiel:
cal.set(2009,3,29,10,00)
add
Um zB. 35 Tage zum Datum zu addieren
cal.add(c.DATE,35)
roll
Datum um 35 Tage „rollieren“(vordrehen),
Monat belibt unverändert
SetTimeInMillis,
getTimeInMillis
das Datum in Millisekunden umwandeln
get
Auslesen von Teilinformationen (YEAR,
MONTH, DAY_OF_MONTH, DAY_OF_WEEK
, HOUR_OF_DAY , MINUTE , SECOND
4.11. Exceptions
Exceptions sind Fehler, Ausnahmen die in einem Programm passieren. Üblicherweise stürzt das
Programm dann ab. Ein gutes Programm tut das allerdings nicht, nur muss der Programmierer
diese Fehler auffangen und behandeln. Als Beispiel nehmen wir dieses Programm
double erg;
erg = 100/0;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -23-
Das Programm muss abstürzen, da eine Division durch 0 nicht gestattet ist.
Exeptions werden immer dann ausgelöst, wenn im Programmfluss ein Fehler auftritt. Im Regelfall
stürzt das Programm mit einer Fehlermeldung ab (bekannt von Windows). Der fleißige
Programmierer kann aber solche Fehler abfangen und darauf reagieren, und somit das Programm
vor Abstürzen schützen.
Klingt kompliziert? Ist es nicht. Schauen wir uns den folgenden Programmcode an
int zahl=0;
boolean err = false;
try
{
zahl = (int) zahl;
}
catch (ArithmeticException ex)
{
System.out.println("Bitte IRGENWAS eingeben!" + ex.getMessage());
err = true;
}
catch(Exception ex2){
System.out.println("Allgemeiner Fehler" + ex.getMessage());
err = true;
}
finally
{
System.out.println("finally wird IMMER ausgeführt");
if (!err)
System.out.println(zahl);
}
Für jeden Fall eines Fehlers gibt es im Allgemeinen einen eigenen Exceptiontyp. Welchen Typ man
abfragen kann, findet man in der Hilfe des Programms. Üblicherweise fängt man Fehler in einem
try catch Block ab.
Passiert im try Block ein Fehler, geht das Programm zum entsprechenden catch Block über, und
arbeitet dort weiter. Man kann hier beliebig viele catch Blöcke definieren. Das Programm stürzt
nun nicht mehr ab, und arbeitet weiter.
Der finally Block wird auf jeden Fall ausgeführt.
4.11.1.
throws im Methodenkopf angeben
Neben dem üblich try-catch Statements, kann man auch im Kopf der betreffenden Methode
eine throws-Klausel einführen. Dadurch stürzt die Methode nicht mehr ab, sondern gibt den Fehler
an die aufrufende Instanz weiter. Die aufrufenden Instanzen können dann auf den Fehler
reagieren.
static double Division(double zahl) throws ArithmeticException,
Exception{
return zahl/0;
}
try{
Division(100.1);
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -24-
catch(ArithmeticException ex){
System.out.println(ex.getMessage());
}
catch(Exception ex){
System.out.println(ex.getMessage());
ex.printStackTrace();
}
Im obigen Beispiel sieht man, das die Methode nicht auf etwaige Exceptions reagiert, sondern
diese mit dem throw Befehl weitergibt. Der throw Befehl ermöglicht es, manuell Exceptions
auszulösen, z.B. so:
throw new ProtocolException();
4.12. Erstellen und Einbinden von Packages
Oft programmiert man Routinen, die man wiederverwenden möchte. Stell dir Methoden vor, die auf
Knopfdruck z.B. die Fläche von Rechtecken, Parallelogrammen oder Trapezen berechnet. Warum
soll man diese Methoden jedes mal neu programmieren wenn man sie benötigt. Hier kommt das
Package ins Spiel. Ein Package ist eine Sammlung von Routinen, die man jederzeit
wiederverwenden kann.
Das Erstellen ist ganz einfach. Wichtig zu wissen ist, das jedes Package ein eigenes
Unterverzeichnis haben muss.
Durch einen einfachen Rechtsklick auf SourcePackages
kann man neue Packages erstellen (hier MathPackage).
Ein Package kann viele *.java Quelldateien beinhalten.
Die *.java Datei beinhaltet als erste Zeile
package MathPackage;
sonst programmiert man wie gewohnt.
Wenn man nun das Package verwenden möchte, muss man das Package mit dem import Befehl
eingliedern (vergleich dazu auch 3.4. Klassen und Packages). Ab dann kann man auf alle
Methoden und Variable zugreifen (beachte die Zugriffsmodifizierer wie public, private).
package testpackages;
import MathPackage.Vierecke;
public class Main {
public static void main(String[] args) {
Vierecke veck = new Vierecke();
System.out.println("Verwendung eines externen
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -25-
Packages ...");
double fl = veck.Flaeche_Rechteck(12, 14);
System.out.println("Fläche eines Rechteckes: " + fl);
}
}
Im Umgang mit Paketen sollte man ein paar Regeln beachten:
1. Was zu einem Paket gehört ist außerhalb unsichtbar
Diese Regel hat den Zweck, dass man in verschiedenen Paketen dieselben Namen
verwenden kann. Man muß bei selbst entwickelten Paketen nur darauf achten, dass es zu
keinen Namenskollisionen innerhalb des Paketes kommt. Man sollte sicherstellen, dass die
eigenen Klassen nur von berechtigten Methoden und Klassen gesehen und manipuliert
werden können.
2. Namen können von einem Paket exportiert werden
Mit dem Zusatz public können Klassen, Methoden, Felder und Konstruktoren exportiert
werden, nicht jedoch Parameter oder lokale Variablen. Eine exportierte Methode ist in
anderen Paketen nur dann sichtbar, wenn auch die zugehörige Klasse exportiert wurde.
3. Exportierte Klassen können in anderen Paketen importiert werden
4.13. Formatierung der Systemstandardausgabe
Nachdem man über System.out.println zwar schnell und komfortabel eine Ausgabe
erzeugen kann, findet man aber keine Möglichkeiten, diese Ausgabe ordentlich zu formatieren.
In den Klassen String und PrintStream gibt es dafür die Methode format().
for(int i=5; i < 199; i += 45)
{
System.out.format(„Aktueller Wert: %3d%n“, i);
}
Die Angabe %3d%n erzwingt eine Ausgabe einer 3-stelligen Ganzzahl und anschließendem
Zeilenvorschub.
Optionen
b
Boolescher Wert
c
Einzelnes Zeichen
d, o, x
Ganzzahl in Dezimal-, Oktal- bzw.
Hexadezimaldarstellung
X
Darstellung in Hexadezimaldarstellung nur mit
großen Buchstaben
f
Gleitkommazahl
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -26-
e, E
Gleitkommazahl mit Exponent bzw. mit
großem „E“
g, G
Gleitkommazahl in gemischter Schreibweise
bzw. mit großem „E“
t
Präfix für Datums-/Zeitangaben, wobei
anschließend angegeben werden muss,
welcher Teil des Date- bzw. CalendarObjektes angegeben wird
(H,M,S,d,m,Y,F,c)
s
Strings und andere Objekte
Man sollte allerdings genau auf Typenkonformität achten!
Einige weitere Beispiele:
//Boolesche Werte
System.out.format("%b %b %2$b %1$b%n", true, false);
//Ganzzahlen
System.out.format("[%d]%n", -2517);
System.out.format("[%7d]%n", -2517);
System.out.format("[%-7d]%n", -2517);
System.out.format("[%(7d]%n", -2517);
System.out.format("[%07d]%n", -2517);
System.out.format("[%,7d]%n", -2517);
System.out.format("%1$d %<o %<x %<X%n", 127);
//Fliesskommazahlen
System.out.format("%f%n", 0.000314);
System.out.format("%1$6.2f %1$6.2e %1$6.2E %1$6.2G%n",
3.141592);
System.out.format("%,8.2f%n", 31415.92);
System.out.format(Locale.ENGLISH, "%,8.2f%n", 31415.92);
//Zeichen und Strings
System.out.format("%c%c%c\n", 97, 64, 98);
System.out.format("%s nein\n", "ja");
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -27-
//Datum/Uhrzeit
Calendar now = Calendar.getInstance();
System.out.format(
"%1$td.%1$tm.%1$tY %1$tH:%1$tM:%1$tS%n",
now
);
System.out.format("%tF%n", now);
System.out.format("%tc%n", now);
4.14. Einlesen der Tastatur
Mit der passenden Klasse ist alles ganz einfach.
Scanner s = new Scanner(System.in);
int x = s.nextInt();
String msg = s.next();
oder so geht es auch ...
import java.io.*;
private String ReadLine(){
BufferedReader in = new BufferedReader(new
InputStreamReader(System.in));
String s ="";
try {
s = in.readLine();
}
catch(IOException ex){
return "";
}
return s;
}
Der BufferedReader übernimmt für uns die Aufgabe das Ende der Eingabe zu suchen. Arbeitet
man mit System.in.Read() erhält man bloß ein Char[] und muss sich selbst um das Auslesen
der gesamten Eingabe kümmern.
4.15. Dateien und Streams
Es gibt Klassen mit denen man Dateien lesen und beschreiben kann.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -28-
File f = new File( dateiname );
byte[] buffer = new byte[ (int) f.length() ];
InputStream in = new FileInputStream( f );
in.read( buffer );
in.close();
In diesem Beispiel wird die gesamte Datei in einen InputStream gelesen, das kann bei großen
Dateien sehr lange dauern, und ist daher nicht zu empfehlen.
Für Textdateien steht eine spezielle Klasse FileWriter und FileReader zur Verfügung. Dazu
muss aber das entsprechende Package eingebunden werden.
class java.io.FileWriter
Writer fw = null;
try
{
fw = new FileWriter( "TextDatei.txt" );
fw.write( "Das ist eine Zeile!" ); //Zeilenvorschub
fw.append( System.getProperty("line.separator") );
}
catch ( IOException e ) {
System.err.println( "Konnte Datei nicht erstellen" );
}
fw.close();
Für das Lesen von Dateien würde man folgende Struktur verwenden
public void ReadFile(String filename){
try{
BufferedReader rd = new BufferedReader(new
FileReader(filename));
//bis zum Ende der Datei lesen
String buffer ="";
while((buffer = rd.readLine()) != null){
//Ausgabe auf die Konsole
System.out.println(buffer);
}
}
catch(FileNotFoundException ex){
}
catch(IOException ex){
}
}
Der entscheidende Teil ist der BufferedReader, der die Aufgabe hat, den Datenstrom aus der
Datei in Strings umzuwandeln. Beachte auch diese Zeile while((buffer = rd.readLine())
!= null). Das ist eine sehr kurze Schreibweise für die Laufbedingung der While-Schleife. Das
bedeutet, das so lange eine Zeile gelesen wird, bis der Datenstrom aus ist, also null.
Für das Schreiben in eine Datei verwendet man den BufferedWriter,siehe anschl. Beispiel.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -29-
Beispiel: Lesen von der Tastatur und Schreiben in eine Datei
Um eine Eingabe von der Tastatur zu verarbeiten, gibt es (vgl. zur Standardausgabe) auch die
Standardeingabe mit System.in. Der Eingabe-Stream System.in ist ein Exemplar der Klasse
InputStream und besitzt somit auch deren Methoden. Die Eingabe wird in diesem Fall mit der
Methode read() vorgenommen.
Hierdurch wird das Array buffer mit den vom Benutzer auf der Standardeingabe eingegebenen
Zeichen Byte-weise gefüllt:
read = System.in.read(buffer, 0, 80);
Im folgenden Beispiel wird nun die Tastatureingabe in die Datei daten.txt gespeichert.
public static void main(String args[]) {
BufferedReader in = new BufferedReader(new
InputStreamReader(System.in));
System.out.print("Tastatureingabe: ");
try { String s = in.readLine();
System.out.println("Kontrollausgabe: "+s);
try{ BufferedWriter out =new BufferedWriter(
new OutputStreamWriter(new
FileOutputStream("daten.txt")));
out.write(s);
out.newLine();
out.close();
System.out.println("Ihre Daten wurden in daten.txt
gespeichert");
}
catch(FileNotFoundException e){
System.out.println(e.getMessage());}}
catch(IOException e){System.out.println(e.getMessage());}}
5. Rekursion
Methoden können in JAVA nicht nur andere Methoden sondern auch sich selbst aufrufen, was man
als rekursiven Aufruf bezeichnet. Diese Technik gehört zum Grundwerkzeug jedes erfahrenen
Programmierers, da es meist weit elegantere Lösungen bietet als iterative Lösungsmöglichkeiten.
Am besten sieht man den Nutzen der Rekursion anhand eines Beispieles:
Wir wollen die Fakultät einer natürlichen Zahl berechnen.
n !=1⋅2⋅3⋅⋅n−1⋅n
Das wäre eine iterative Definition.
Rekursiv versucht man nun das „Problem“ auf sich selbst zurück zu führen.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -30-
Wir erkennen, dass die ersten n-1 Faktoren des Produkts die Zahl (n – 1)! ergeben, was uns zu
einer rekursiven Definition führt:
n! = (n – 1) ! * n
n! = 1
für
für
n>1
n=1
Somit wird das Problem auf ein etwas kleineres gleichartiges Problem zurückgeführt, was man
solange macht, bis die Berechnung abgeschlossen ist.
Die Implementierung könnte nun so aussehen:
long fact(int n)
{if(n==1) {return 1;}
else { return fact(n-1)*n;}}
Man könnte vereinfacht sagen:
Wenn (Problem klein genug)
führe nichtrekursiven Zweig ausführung
sonst
führe rekursiven Zweig aus
5.1. Bespiel: Fibonacci Zahlen
Die Fibonaccifolge stellt ein sehr einfaches Beispiel für die rekursive Programmierung dar.
Allerdings muss man leider auch beachten, dass die rekursive Lösung in diesem Fall die
ressourcenintensivste darstellt, da die Funktion mehrfach mit denselben Parametern aufgerufen
wird, was wiedeum viel Speicher benötigt.
Trotzdem kann man anhand dieses Beispieles Rekursionen sehr leicht analysieren und verstehen.
public static long fib(int a){
if (a==1||a==2) return 1;
else return fib(a-1)+fib(a-2);
}
Für die Parameter 1 und 2 wird jeweils 1 zurückgegeben, bei allen anderen Zahlen wird die
Funktion mit den Parametern a-1 und a-2 aufgerufen.
5.2. Beispiel Quicksort
Ein wichtige Anwendung der Rekursion stellen Sortier- und Suchalgorithmen dar. Man nimmt eine
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -31-
Liste von Elementen und teilt diese in zwei Hälften. Zunächst wird die zu sortierende Liste in zwei
Teillisten („linke“ und „rechte“ Teilliste) getrennt. Dazu wählt Quicksort ein sogenanntes
Pivotelement aus der Liste aus. Alle Elemente, die kleiner als das Pivotelement sind, kommen in
die linke Teilliste, und alle, die größer sind, in die rechte Teilliste. Die Elemente, die gleich dem
Pivotelement sind, können sich beliebig auf die Teillisten verteilen. Nach der Aufteilung sind die
Elemente der linken Liste kleiner oder gleich den Elementen der rechten Liste.
Anschließend muss man also nur noch jede Teilliste in sich sortieren, um die Sortierung zu
vollenden. Dazu wird der Quicksort-Algorithmus jeweils auf der linken und auf der rechten Teilliste
ausgeführt. Jede Teilliste wird dann wieder in zwei Teillisten aufgeteilt und auf diese jeweils wieder
der Quicksort-Algorithmus angewandt, und so fort. Diese Selbstaufrufe werden als Rekursion
bezeichnet. Wenn eine Teilliste der Länge eins oder null auftritt, so ist diese bereits sortiert und es
erfolgt der Abbruch der Rekursion, d.h. für diese Teilliste wird Quicksort nicht mehr aufgerufen.
Die Längen der Teillisten ergeben sich aus der Wahl des Pivotelements. Idealerweise wählt man
das Pivot so, dass sich zwei etwa gleich lange Listen ergeben, dann arbeitet Quicksort am
effizientesten. Es sollte also etwa gleich viele Elemente kleiner als das Pivot und größer als das
Pivot geben.
daten[0], daten[1],... , daten[n-1].
funktion quicksort(links, rechts)
falls links < rechts dann
teiler := teile(links, rechts)
quicksort(links, teiler-1)
quicksort(teiler+1, rechts)
ende
ende
Die folgende Implementierung der Funktion teile teilt das Feld so, dass sich das Pivotelement an
seiner endgültigen Position befindet und alle kleineren Elemente davor stehen, während alle
größeren danach kommen:
funktion teile(links, rechts)
i := links
// Starte mit j links vom Pivotelement
j := rechts – 1
pivot := daten[rechts]
wiederhole
// Suche von links ein Element, welches größer als das
Pivotelement ist
wiederhole solange daten[i] ≤ pivot und i < rechts
i := i + 1
ende
// Suche von rechts ein Element, welches kleiner als
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -32-
das Pivotelement ist
wiederhole solange daten[j] ≥ pivot und j > links
j := j - 1
ende
falls i < j dann tausche daten[i] mit daten[j]
solange i < j // solange i an j nicht vorbeigelaufen ist
// Tausche Pivotelement (daten[rechts]) mit neuer
endgültiger Position (daten[i])
falls daten[i] > pivot
tausche daten[i] mit daten[rechts]
ende
// gib die Position des Pivotelements zurück
antworte i
ende
6. OOP – Objektorientiertes Programmieren
Alle modernen Programmiersprachen setzen auf Objekte beim Programmieren. Die
Programmierung wird dadurch viel einfacher in der Handhabung. Anstatt eines linearen Codes hat
man Objekte zur Verfügung, die gewisse Aufgaben erledigen können. Diese Objekte erstellt man,
wenn man sie benötigt und teilt ihnen Aufgaben zu. Im Allgemeinen ist OOP flexibler,
leistungsfähiger und bei größeren Programmen einfach übersichtlicher.
Die Übersichtlichkeit kann man mit diversen Zugriffsmodifizierer (vergl. 6.1. Zugriffsmodifizierer auf
Seite 36) steuern.
Sehen wir uns ein Beispiel aus der Mathematik an
Shape
Alle angeführten Objekte sind abgeleitet
von der Basisklasse Shape.
● Die Eigenschaften der Basisklasse
werden an die nachfolgenden Objekte
vererbt
● Jedes Objekt hat Eigenschaften und
Methoden
● Methoden der Basisklasse könne
überschrieben werden
●
Rechteck
Ellipse
Quadrat
Kreis
Warum leitet sich z.B. ein Quadrat von einem Rechteck ab? Die Antwort kennst du aus der
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -33-
Mathematik. Jedes Quadrat ist auch ein Rechteck, das Quadrat ist nur eine spezielle Form des
Rechtecks. Wenn also die Fläche eines Rechtecks mit Seite x Seite zu berechnen ist, dann ist es
auch beim Quadrat so.
Shape ist das allgemeinste Objekt. Es hat allgemeine Eigenschaften eines Körpers in 2D, also
eine Begrenzungslinie, eine Fläche und einen Umfang etc.
Die Definition könnte so aussehen
Shape
Objektnamen
Linie: 2px
Linenfarbe:rot
Dichte: 3.4
Eigenschaften
Zeichnen()
Flaeche(); Umfang();Volumen();
Masse()
Methoden
Von dieser Klasse leiten wir nun das Rechteck ab, das ist eine Spezialisierung des Shapes.
Rechteck
Linie, Linenfarbe
Laenge
Breite
Länge und Breite sind eine spezielle Eigenschaft von eine
Rechteck, während Linie, Linienfarbe bereits von Shape geerbt
worden sind,
Zeichnen()
Flaeche()
Umfang()
Diagonale()
Die Methode Diagonale() ist wieder eine spezielle Eigenschaft, der
Rest wurde geerbt.
Der dazu passende Quellcode sieht so aus:
public class Shape2D {
protected int Linie;
protected int Linienfarbe;
protected double dichte = 1.0;
public Shape2D () {
}
public abstract void Zeichnen ();
public abstract double Volumen ();
public double Masse (){
return Volumen * dichte;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -34-
/*
Hier wird bereits mit dem Volumen gerechnet, obwohl es
abstrakt ist!
*/
}
public void Flaeche () {
}
public void Umfang () {
}
}
Die Methode Zeichnen() ist abstrakt, es muss nur der Kopf definiert werden. Man kann zwar jedes
Objekt der Klasse Shape zeichnen, allerdings muss dies für jedes Objekt extra implementiert
werden. Man nennt Klassen, die zumindest eine abstrakte Methode enthalten, abstrakte Klassen.
Man sollte allerdings beachten, dass man keine Objekte dieser Klasse erzeugen kann, sehr wohl
aber von den Unterklassen.
Ein kleines Beispiel soll das verdeutlichen:
abstract class Animal{
boolean
likes(String food){return false;}
abstract void speak();
void getAngry(){speak();}
Wir haben also eine abstrakte Tierklasse, in der zwar jedes Tier speaken kann, allerdings spricht
jedes Tier anders. Wenn wir jetzt ein neues Objekt erzeugen wollen, müssen wir vorsichtig
agieren:
Animal a1 = new Animal(); //ist nicht erlaubt
Animal a2 = new Bird();
//ist erlaubt
a2.speak(); // liefert „beep“
Wieder zurück zur Geometrie:
Die Methode Flaeche() hingegen ist nicht abstrakt, und muss bereits hier aus programmiert
werden.
Das abgeleitete Rechteck sieht nun so aus:
public class Rechteck extends Shape2D {
public int Laenge;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -35-
public int Breite;
public Rechteck () {
}
public void Diagonal () {
}
public void Zeichnen () {
}
@Override
public void Umfang () {
}
@Override
public void Flaeche () {
}
}
Eine Klasse wird von einer anderen Klasse abgeleitet mit der Schreibweise Neue Klasse
extends Mutterklasse.
Die Methode Flaeche() muss mit @Override neu definiert werden. Ansonsten weiß man nicht ob
die Methode Flaeche() von der Klasse Shape oder von der Klasse Rechteck kommt!
Rechteck definiert neu Laenge und Breite, hat aber zusätzlich noch die Eigenschaften Linie
und Linienfarbe der Klasse Shape (vererbt).
Überlege selbst, wir die Klasse Quadrat aussehen muss!
6.1. Zugriffsmodifizierer
Zugriffsmodifizierer steuern die Sichtbarkeit von Elementen eines Objektes. Die wichtigsten für uns
sind
•
public
•
private
•
protected
Eigenschaften oder Methoden die mit public gekennzeichnet sind, dürfen von außerhalb des
Objektes angesprochen werden. Mit private gekennzeichnete Element sind NUR innerhalb des
Objektes verwendbar. Wenn man eine Spezialisierung einer Klasse vornimmt (mit extend ableitet),
sollte man mit protected arbeiten.
Fehlt der Zugriffsmodifizierer, das ist das Element immer als public anzusehen.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -36-
6.2. Getter und Setter
Getter und Setter sind Methoden, die die Eigenschaften eines Objektes schützen sollen. Diese
Methoden können Fehlerbehandlungen oder Umwandlungen durchführen.
public class Kreis {
private int Radius=0;
//Getter
public int getRadius () {
return Radius;
}
//Setter
public void setRadius (int val) {
if(Radius > 0){
this. Radius = val;
}
}
}
Die eigentliche Eigenschaft ist private, also geschützt. Die Getter heißen get<Eigenschaft>
und set<Eigenschaft>.
Wie man im Beispiel erkennen kann, wird nur dann ein Radius gespeichert, wenn dieser größer 0
ist, also hier wird auf die Eingabe reagiert, und so die Eigenschaft geschützt.
6.3. Konstruktoren
Konstruktoren dienen dazu, beim Erstellen des Objektes Aufgaben zu erledigen.
Ein Konstruktor heißt immer so wie die Klasse / Objekt selbst.
public class Rechteck extends Shape2D {
public int Laenge;
public int Breite;
public Rechteck (int b, int l) {
this.Laenge = l;
this.Breite = b;
}
}
Im obigen Beispiel werden dem Konstruktor 2 Parameter mit übergeben. Diese Parameter sind die
Länge und die Breite des Rechtecks. Das Erstellen des Objektes sieht so aus
Rechteck = new Rechteck(12,10);
Es sind nun zwingend diese beiden Parameter notwendig.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -37-
Man kann aber auch mehrere Konstruktoren schreiben, und so steuern, wie man das Objekt
anlegen möchte.
public class Rechteck extends Shape2D {
public int Laenge;
public int Breite;
public Rechteck () {
}
public Rechteck (int b, int l) {
this.Laenge = l;
this.Breite = b;
}
}
Im obigen Beispiel sieht man 2 Konstruktoren. Man kann nun den einen oder den anderen beim
Erstellen des Objektes verwenden. Diesen Vorgang nennt man Überladung einer Methode.
Man kann auch den einen Konstruktor aus dem anderen Konstruktor aufrufen. Sehen wir uns
dieses Beispiel an
Konto(String inhaber) {
this.inhaber = inhaber;
}
Konto(String inhaber, double stand) {
this(inhaber); /* Aufruf des Konstruktors Konto(String inh) */
this.stand = stand;
}
Konto(String inhaber, double stand, boolean gesperrt) {
this(inhaber, stand);
this.gesperrt = gesperrt;
}
Mit this() werden hier die anderen Konstruktoren geladen.
6.4. Die static Methode
Man kann eine Methode einer Klasse als static definieren, z.B.
public class FileManagement {
public static String[] ReadDir(String path){
… tu was ...
}
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -38-
Was ist damit erreicht. Eine static gekennzeichnete Methode, kann per Klassen Namen
aufgerufen werden. Das Erzeugen einer Instanz ist nicht mehr nötig.
String[] ergebnis =
FileManagement.ReadDir(Path);
anstatt von
FileManagement fm = new FileManagement();
String[] ergebnis = fm.ReadDir(Path);
ist ausreichend.
6.5. Mehrfachvererbungen - Interfaces
Das Problem: Eine Klasse soll von zwei Vorgängern abgeleitet werden, also eine
Mehrfachvererbung. Wie geht das?
Das Geheimnis sind Interfaces. Das sind rein abstrakte Klassen, die nur die Aufgabe haben, an
Subklassen zu vererben.
Schauen wir uns folgendes Beispiel an:
Die einzelnen Baumarten sollen sowohl von der abstrakten Klasse Holzarten, als auch von einer
Klasse Kostenabrechnung abgeleitet werden. Die Klassen könnten so aussehen
public interface kostenrechnung {
public double laenge = 0;
public double breite = 0;
public double hoehe = 0;
public abstract void Kosten();
public abstract void Festmeter();
}
Vererbt werden folgende Eigenschaften:
public interface holzarten {
public double preis = 0;
public byte lieferzeit = 0;
public String bezeichnung = "";
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -39-
Jetzt wollen wir, das alle Holzarten von beiden Klassen, also holzarten und kostenrechnung
erben.
public class holz implements kostenrechnung, holzarten{
public double Kosten(){
return Volumen() * preis;
}
public double Volumen(){
return laenge * breite * hoehe;
}
}
Und schon sind wir fertig. Getrennt durch einen Beistrich kann man beliebig viele Interfaces für
eine Klasse bekommen.
6.6. Verwendung der UML - Unified Modeling Language
Wenn das Modul UML installiert ist, kann man diese Sprache verwenden um ein Rohgerüst von
Klassen zu erzeugen. Man zeichnet einfach die Klassen und kann sich auf Knopfdruck den
Quellcode erstellen lassen. Dazu muss man ein bestehendes Projekt angeben, in dem die *.java
Dateien erstellt werden. Zusätzlich werden auch die entsprechenden Get- und SetMethoden
erstellt (siehe dazu 6.2. Getter und Setter).
Das obige Beispiel sieht dann so aus:
Abbildung 1: UML Modell aus Netbeans
Der Pfeil bedeutet die Abhängigkeit der Klassen zueinander. Der Pfeil zeigt dabei auf die
Mutterklasse. Mit einem Rechten Mausklick und Generate Code, wird die Java Datei erstellt.
Diese sehen dann so aus.
public class Shape2D {
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -40-
private int Linie;
private int Linienfarbe;
public Shape2D () {
}
public int getLinie () {
return Linie;
}
public void setLinie (int val) {
this.Linie = val;
}
public int getLinienfarbe () {
return Linienfarbe;
}
public void setLinienfarbe (int val) {
this.Linienfarbe = val;
}
public abstract void Zeichnen () {
}
public abstract void Flaeche () {
}
public abstract void Umfang () {
}
}
und
public class Rechteck extends Shape2D {
private int Laenge;
private int Breite;
public Rechteck () {
}
public void Diagonal () {
}
public int getBreite () {
return Breite;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -41-
}
public void setBreite (int val) {
this.Breite = val;
}
public int getLaenge () {
return Laenge;
}
public void setLaenge (int val) {
this.Laenge = val;
}
public void Zeichnen () {
}
public void Umfang () {
}
public void Flaeche () {
}
}
Also bekommt man ein Grundgerüst, das nur noch aus programmiert werden muss!
7. Fragen wir Dr. Java, Good to know
7.1. Bildschirmauflösung abfragen
Wie zentriere ich ein Fenster? Wie passe ich ein Fenster an den Monitor an?
Nun so
Dimension screenResolution = sys.getScreenResolution();
MainForm f = new MainForm();
Dimension fsize = new Dimension(
(int)(screenResolution.width*0.75),
(int)(screenResolution.height*0.9)
);
f.setSize(fsize);
f.setVisible(true);
Zuerst frage ich die Bildschirmauflösung ab, und dann kann ich wie hier gezeigt, die Größe des
Fensters an den Monitor anpassen.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -42-
7.2. Dynamisches Erstellen von Elementen
Was tun, wenn zur Laufzeit dynamische Elemente erzeugt werden müssen? Als Beispiel wollen wir
einige Buttons dynamisch erzeugen.
Collection btnList = new LinkedList<JButton>();
/*Erstellen von 10 Buttons*/
for(int i=0; i<10; i++){
JButton btn = new Jbutton("Button"+i);
btn.setVisible( true );
/*KlickMethode per Listener zuweisen*/
btn.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String buttonText = e.getActionCommand();
}
});
/*Button zur Collection hinzufügen*/
btnList.add(btn);
/*der Form zuordnen*/
this.add(btn);
/*neuzeichnen auslösen*/
this.setVisible(true);
7.3. Warum erfolgt kein Repaint einer Komponente?
Wenn dir das passiert, dann denke an folgendes
•
mache ein revalidate()
•
mache ein repaint()
z.B. hast du ein Panel das sich neu zeichnen muss, das macht du also so
PanelKlassen.revalidate();
PanelKlassen.repaint();
Nun sollte es klappen!
8. Threads mit Java
8.1. Threads über das Interface Runnable
Threads können über ein so genanntes Interface erzeugt werden.
interface java.lang.Runnable
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -43-
Dieses Interface bietet nur die run() Methode und lässt den Thread parallel zum Hauptprogramm
ablaufen.
public class DateCommand implements Runnable
{
@Override
public void run(){
for ( int i = 0; i < 20; i++ )
System.out.println( new java.util.Date() );
}
}
in Arbeit
8.2. wait() und notify()
Manchmal möchte man auf das Ende eines Threads warten, weil dieser z.B. sehr lange etwas
berechnen muss. In diesem Fall hält man den aufrufenden Thread an, und schickt diesen schlafen.
Hier ein Beispiel (Quelle: www.tutorials.de/java/):
Der MasterThread wartet solange, bis der ClientThread ihn wieder aufweckt.
public class MasterThread extends Thread {
private ExecutorService service =
Executors.newCachedThreadPool();
@Override
public void run() {
System.out.println("MasterThread start");
synchronized (this) {
service.execute(new ChildThread(this));
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MasterThread ende");
}
class ChildThread implements Runnable {
private MasterThread masterThread;
ChildThread(MasterThread masterThread) {
this.masterThread = masterThread;
}
@Override
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -44-
public void run() {
try {
System.out.println("ChildThread start");
System.out.println("ChildThread ende");
}
finally { // Sicherstellen, dass Parent geweckt wird
synchronized (masterThread){
masterThread.notify();
}
}
}
}
8.3. Zugriff auf Daten aus einem Thread heraus
Um auf eine gemeinsame Klasse aus Threads heraus zugreifen zu können, muss der Zugriff
threadsicher sein. Wenn ein Thread gerade auf sagen wir eine Variable zugreift, muss ein
anderer Thread warten bis er dran ist. Das erreicht man mit dem synchronized() Statement.
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
Im Thread selbst, spricht man die obigen Methoden so an
synchronized(counter){
counter.increment();
}
Das synchronized() Statement macht den Zugriff threadsischer, d.h. das ein anderer Thread
solange wartet bis er dran ist.
8.3.1.
Synchronisieren mit einem Objekt
Man kann auch so einen Zugriff starten
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -45-
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) { c1++; }
}
public void inc2() {
synchronized(lock2) { c2++; }
}
}
8.4. Executors
Liefern ein Thread Management und ist nützlich für größere Anwendungen.
Mit Zum Beispiel Threadpools, kann man eine fixe Anzahl von Threads arbeiten lassen. Der
Executor startet dann automatisch die nächsten anstehenden Threads.
Man muss sich also nicht um die Abarbeitung der Threads mehr kümmern. Sehen wir uns ein
Beispiel an
//Anzahl der CpU Cores ermitteln
int processors = Runtime.getRuntime().availableProcessors();
//Thread Pool
ExecutorService executor =Executors.newFixedThreadPool(processors);
//100 Bilder laden un umrechnen
for(int i=0; i<100; i++){
ThumbLoadWorker thumbworker = new ThumbLoadWorker(
new StaticThumbLoader(), filename[i]);
executor.submit(thumbworker);
}
//keine Threads werden mehr akzeptiert
executor.shutdown();
Hier werden 100 Bilder in Threads geladen und zu einem Thumbnail verkleinert. Es arbeiten immer
so viele Threads, so viele CPU Cores der Computer hat.
Die fertigen Thumbnails werden über das statische Objekt StaticThumbLoader weiter
verarbeitet.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -46-
9. Grafische Anwendungen mit SWING
Grafische Oberflächen programmieren wir mit der SWING Oberfläche. Dazu erstellt man eine
entsprechende Desktop Application. Es steht nun eine grafische (Design) und eine Quellcode
(Source) Oberfläche bereit.
Im Design Modus kann man Buttons, Panels und andere Steuerelemente auf dem Fenster
platzieren, z.B.
Das Aussehen kann man für jedes Steuerelement über die Eigenschaften einstellen.
9.1. Mehrzeilige Labels
Sind kein Problem, wenn man genau die Hilfe liest.
Stellt man <html> vor den Text, kann man den Text mit html-Tags behandeln. Also zum Beispiel
ergibt
jLabel3.setText("<html>Hier stellst du Parameter der Fotogallerie
ein<br>alle die du möchtest");
einen zweizeiligen Label.
9.2. Actions und Events
Jedes Steuerelement kann diverse Aufgaben bekommen. Nehmen wir als Beispiel einen Button.
Dessen Eigenschaften und Events sehen so aus:
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -47-
Events sind so was wie: Maus ist über dem Steuerelement, Angeklickt u.s.w.
Klickt man in das Feld <none> eines Events, wird ein Name vorgeschlagen. Bestätigt man den
Namen mit Enter, springt man an die entsprechende Stelle im Quellcode.
mit dem Quellcode
private void jButton1ActionPerformed(java.awt.event.ActionEventevt)
{
// TODO add your handling code here:
int test = 0;
System.exit(0);
}
9.3. Mausereignisse erstellen
Mausereignisse werden als erstes per Interface „geladen“.
public class AnimApplet extends Applet implements Runnable,
MouseListener, MouseMotionListener {
Je nach dem, welche Ereignisse man benötigt, wählt man ein Interface aus. Mit dem Netbeans
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -48-
Editor kannst du alle Ereignisse auch per grafischer Oberfläche aktivieren, aber im Prinzip passiert
genau das, was nun beschrieben wird.
Nehmen wir an, wir haben ein Panel erstellt, das auf Mausereignisse reagieren soll:
mainPanel = new Jpanel();
this.add(mainPanel, BorderLayout.CENTER);
mainPanel.addMouseMotionListener(new MausMove());
mainPanel.addMouseListener(new MausPanel());
Wie man sieht, werden hier zwei unterschiedliche Maus-Listener verwendet, denen zwei Klassen
zugewiesen werden, nämlich: MausMove() und MausPanel().
Diese Inline Klassen, werden innerhalb der aktuellen Klasse erzeugt.
class MausMove implements MouseMotionListener{
public void mouseDragged(MouseEvent e){
}
public void mouseMoved(MouseEvent e) {
}
}
und
class MausPanel implements MouseListener {
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
}
Netbeans hilft uns hier, und setzt auf Knopfdruck alle möglichen Mausereignisse ein.
Und nun braucht man nur noch in die entsprechenden Klassen eintragen, was passieren soll,
wenn dieses Ereignis eintritt.
9.4. Layout Manger
Die Ausrichtung von Elementen kann man mit 3 Methoden steuern
1. FlowLayout: Zeilenweise Anordnung
2. BorderLayout: Anordnung in den vier Himmelrichtungen (Rahmen) und einem
Mittelbereich
3. GridLayout: Anordnung in einem Gitter mit n gleichgroßen Zellen
9.4.1.
FlowLayout
this.setLayout(new FlowLayout());
JButton MyButton1 = new JButton("MyButton 1");
JButton MyButton2 = new JButton("MyButton 2");
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -49-
JButton MyButton3 = new JButton("MyButton 3");
add(MyButton1);
add(MyButton2);
add(MyButton3);
liefert dieses Ergebnis
Abbildung 2: FlowLayout
FlowLayout fügt zeilenweise in die Oberfläche ein, und jeweils zentriert. Ist die erste Zeile voll, wird
die nächste Zeile eröffnet.
9.4.2.
BorderLayout
initComponents();
this.setLayout(new BorderLayout());
JButton MyButton1 = new JButton("MyButton 1");
JButton MyButton2 = new JButton("MyButton 2");
JButton MyButton3 = new JButton("MyButton 3");
add(MyButton1, BorderLayout.NORTH);
add(MyButton2, BorderLayout.SOUTH);
add(MyButton3, BorderLayout.LINE_END);
liefert
Abbildung 3: BorderLayout
Hier kann man in die vier Himmelsrichtungen ausrichten.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
9.4.3.
Seite -50-
GridLayout
kein Beispiel, Verwendung wie die anderen Layouts
9.4.4.
LayoutManager deaktivieren
mit
setLayout(null);
9.4.5.
Weitere Beispiele zum Layout
public class Flow2 extends Applet{
public void init()
{
setLayout(new FlowLayout(FlowLayout.RIGHT));
for (int i = 0; i < 4; i++)
add(new Button("Button #" + i));
}
}
Ein Beispiel um einen Button auszurichten
setLayout(new BorderLayout);
Start = new Button("Start");
add(Start, BorderLayout.CENTER);
9.5. Dialoge
9.5.1.
FileOpen Dialog
Hierzu gibt es ein eigenes Objekt, das man z.B. bei einer Button Action anwenden kann
private void jButton1ActionPerformed(java.awt.event.ActionEvent
evt) {
JFileChooser fs = new JfileChooser();
int returnVal = fs.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = fs.getSelectedFile();
} else {
System.out.println("File access cancelled by user.");
}
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -51-
Das Ergebnis sieht dann in etwa so aus
Den angezeigten Dateityp kann man mit einem Filter einstellen, das könnte dann so aussehen
ExampleFileFilter filter = new ExampleFileFilter();
filter.addExtension("jpg");
filter.addExtension("gif");
filter.setDescription("JPG & GIF Images");
chooser.setFileFilter(filter);
9.6. Die Sache mit den Pfaden, Icons, Images und
Dateien
Öfters kommt es vor, das man ein Image aus einem Verzeichnis laden möchte. Wie mache ich das
zur Laufzeit?
Nehmen wir an, wir wollen aus dem Package rimages das Bild
bird24.png als Icon für unser Fenster verwenden. Wir bekommen
hier eine getResource() Methode zur Verfügung gestellt. Das ist
nicht der einzige Weg, aber es reicht uns hier, diese Möglichkeit
zu sehen. Und so geht es
URL imgURL =
getClass().getResource(
"/rimages/bird24.png"
);
this.setIconImage(
(new ImageIcon(imgURL)).getImage());
Damit haben wir die Möglichkeit, Images, Icons oder alle anderen Dateien aus einem Package zu
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -52-
laden. Daher gilt ab jetzt folgender Ratschlag:
Dateien die man zur Laufzeit einbinden möchte,
sollten immer in einem Package
liegen!
9.7. Die Sache mit dem JAR-File
Wenn allerdings aus einem JAR File der Befehl getClass().getResource() verwendet wird,
funktioniert das nicht!
(bin mir nicht ganz sicher)
Es funktioniert dann nur getClass().getResourceAsStream(), was einen InputStream liefert.
Das sollte man beachten und auch ausführlich testen!
10. SWING Komponenten im Detail
10.1. JTable Model
Das TableModel definiert die Daten, die die Tabelle anzeigt. Das Model liefert Aufschluss darüber,
welche Werte eine Zelle hat, wobei es auch die Anzahl der Spalten und Zeilen definiert. Abhängig
von Zeile und Spalte entscheidet das Model darüber, ob die Zelle editierbar ist, wobei der
erfolgreich geänderte Wert mittels setValue(Object value) ins Model zurückgeschrieben wird.
Wichtig ist die Zeile types, denn hier wird angegebne welche Daten dargestellt werden.
z.B. eine Tabelle TabellePersonen extends JTable könnte so aussehen
public TabellePersonen(Object[] columnNames, Object[][] data) {
super();
/* Was wird gespeichert */
setModel(new DefaultTableModel(data,columnNames){
Class[] types = new Class [] {
Integer.class, String.class, String.class, String.class,
String.class
};
/* Editierbar? */
boolean[] canEdit = new boolean [] {
false, true, true, false, false};
@Override
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -53-
@Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
10.2. Auf Ereignisse reagieren
Wenn sich etwas in der Tabelle ändert möchte man darauf reagieren, da könnte so ablaufen
/* Daten in der Tabelle haben sich geändert */
this.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
System.out.println(e);
}
});
/* welche Zeile ist selektiert? */
this.getSelectionModel().addListSelectionListener(new
ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
if(e.getValueIsAdjusting()) return;
}
});
10.3. Zellen darstellen un bearbeiten
Oft möchte man eine Zelle bestimmt darstellen, z.B. mit einem Button, oder man möchte auf eine
Eingabe reagieren. Dazu bnietet die Tabelle zwei Dinge an
1. Renderer, der die Darstellung der Zelle übernimmt
2. Editor, der die Bearbeitung der Zelle übernimmt.
10.3.1.
Ein Renderer
Angenommen wir haben so ein Model
setModel(new DefaultTableModel(data,columnNames){
Class[] types = new Class [] {
Integer.class, String.class, String.class, String.class,
String.class
};
Dann kann man für eine Klasse einen eigenen Renderer angeben, z.B.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -54-
this.setDefaultRenderer(Integer.class, new ZahlenRenderer());
this.setDefaultRenderer(Object.class, new IrgendwasRenderer());
10.4. Ein konkretes Beispiel
Angenommen eine Zelle soll einen Button bekommen. Wie macht man das?
Wir brauchen für die Zelle einen Renderer und einen Editor.
Die Tabelle wird so angelegt
setModel(new DefaultTableModel(data,columnNames){
Class[] types = new Class [] {
Integer.class, String.class, String.class,
String.class, Note.class, Aktionen.class};
Wir legen hier eine eigene Klasse Aktionen an. Sie dient eigentlich nnur zur Identifikation der
Klasse in der Zelle, und kann daher inline, leer definiert werden.
private class Aktionen{}
Nun können wir den entsprechenden Renderer zuweisen
this.setDefaultRenderer(Aktionen.class, new AktionenRenderer());
Wir sehen hier unser Dummy Klasse. Der Renderer selbst sieht so aus
private class AktionenRenderer extends JPanel implements
TableCellRenderer {
@Override
public Component getTableCellRendererComponent(JTable table,
Object value,boolean isSelected, boolean hasFocus, int row,
int column) {
this.removeAll();
this.setLayout(new FlowLayout(FlowLayout.RIGHT, 4, 0));
JButton btn1 = new JButton();
btn1.setIcon(
new ImageIcon(getClass().getResource
("/icons/add.png")));
btn1.setPreferredSize(new java.awt.Dimension(25, 25));
this.add(btn1);
return this;
}
}
Dieser Renderer ist von JPanel abgeleitet, das this bezieht sich darauf. Darin können wir nun
unseren Button definieren (muss nicht in einem Panel sein, aber warum nicht).
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -55-
Nun kommt noch der Editor, mit dem wir auf die Benutzung des Buttons reagieren!
Hier muss man beachten, das der Editor wiederum einen neuen Button zeichnet, der sich von dem
des Renderes unterscheidet. Am besten übergibt man beiden den selben Button!
class AktionenEditor extends JButton implements TableCellEditor {
private List<CellEditorListener> listeners =
new ArrayList<CellEditorListener>();
public AktionenEditor() {
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Button: Not
supported yet.");
}
});
}
@Override
public JButton getTableCellEditorComponent( JTable table,
Object value, boolean isSelected, int row, int column ) {
/* Diese Methode wird von der JTable aufgerufen, wenn der
Editor angezeigt werden soll */
return this;
}
@Override
public void addCellEditorListener( CellEditorListener l ) {
listeners.add( l );
}
@Override
public void cancelCellEditing() {
/* Falls abgebrochen wird, werden alle Listeners informiert */
ChangeEvent event = new ChangeEvent( this );
for( CellEditorListener listener : listeners.toArray( new
CellEditorListener[ listeners.size() ] ))
listener.editingCanceled( event );
}
@Override
public Object getCellEditorValue() {
/* Button hat keinen Wert */
return null;
}
@Override
/* Immer editierbar, d.h. Button immer anklickbar */
public boolean isCellEditable( EventObject anEvent ) {
return true;
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -56-
@Override
public void removeCellEditorListener( CellEditorListener l ) {
listeners.remove( l );
}
@Override
public boolean shouldSelectCell( EventObject anEvent ) {
return true;
}
@Override
public boolean stopCellEditing() {
/* Ansonsten werden die Listener vom stop unterrichtet */
ChangeEvent event = new ChangeEvent( this );
for( CellEditorListener listener : listeners.toArray( new
CellEditorListener[ listeners.size() ] ))
listener.editingStopped( event );
return true;
}
}
Diese Klasse ist etwas größer, man kann aber im Prinzip alles kopieren!
10.5. Renderer und Editor in einer Klasse
Im obigen Beispiel gab es zwei verschiedene Buttons für Editor und Renderer. Besser ist es nur
einen Button zu haben, und alles in einer Klasse zusammenzufassen.
In der Tabelle wird so der Button aktiviert
ButtonInColumn btnCol = new ButtonInColumn(this, mybtn, delete, 4);
this.setDefaultRenderer(Aktionen.class, btnCol);
this.setDefaultEditor(Aktionen.class, btnCol);
Die Klasse ButtonInColumn bekommt dabei übergebn
•
die Tabelle
•
den Button der angezeigt wird
•
die Action die beim Klicken ausgeführt wird
•
die Spalte in der Tabelle
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -57-
Änderungen an Tabelle
this.getModel().addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent e) {
System.out.println(e);
}
});
11. GDI
11.1. Zeichnen in einem Panel
Wo man zeichnet ist relativ egal. Ich zeichne meistens in ein Panel, weil ich das Panel auf der
Seite beliebig positionieren kann. Dazu erstellen wir eine eigene Klasse die so aussieht
package MyPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.*;
public class DrawPanel extends Jpanel{
@Override
protected void paintComponent( Graphics g ){
//hier wird gezeichnet
}
}
Wir leiten also vom JPanel ab, und überschreiben dessen Paint Methode. Die Paint Methode
wird automatisch aufgerufen, um das brauchen wir uns nicht kümmern.
Schreiben wir hier unsere Zeichenroutinen hinein, zeichnen wir innerhalb des Panel's.
Das war's auch schon, so einfach ist das :) .
11.2. Transformationen
Der Koordinatenursprung von Objekten liegt immer links oben. Möchte man z.B. den
Koordinatenursprung in die Mitte des Objektes verschieben, kann man eine Transformation wie
folgt verwenden
public void paintComponent(Graphics gIn){
Graphics2D g = (Graphics2D)gIn.create();
g.translate(getWidth() / 2, getHeight() / 2);
g.rotate(30.0 * Math.PI / 180.0);
g.setFont(new Font("Sans", Font.BOLD, 24));
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -58-
g.drawText("M");
g.destroy();
}
Hier wird mit dem Graphics2D Objekt der Koordinatenursprung in die Mitte der Komponente
geschoben, und das Koordinatensystem um 30° gedreht. Das Ergebnis sieht so aus
11.3. Affine Transformation
Man kann auch dieses Objekt verwenden, um eine Transformation als ein „Makro“ zu speichern.
AffineTransform a = new AffineTransformgetTranslateInstance
(getWidth() / 2, getHeight() / 2);
public void paintComponent(Graphics gIn){
Graphics2D g = (Graphics2D)gIn.create();
g.setTransform(a);
g.setFont(new Font("Sans", Font.BOLD, 24));
g.drawText("M");
g.destroy();
}
Weitere Informationen findest du hier
http://java.sun.com/j2se/1.5.0/docs/api/java/awt/geom/AffineTransform.html.
11.4. Punktierte Linie zeichnen
Als Beispiel in der Paint Methode
g2.setColor(new Color(c, c, c));
Stroke stroke = new BasicStroke(1,BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL, 0, new float[] { 2, 2 }, 0);
g2.setStroke(stroke);
… Linie zeichnen …
12. Erstellen von Java Applets für Webseiten
http://java.sun.com/docs/books/tutorial/deployment/applet/
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -59-
12.1. Grundlagen
Applets werden in Webseiten dargestellt, was die Möglichkeit bietet, JAVA Programme im Internet
zu verbreiten. Es gibt aber einige Einschränkungen zu einem vollwertigen Projekt, immerhin wird
ein Programm aus dem Internet auf den Computer geladen, und das ist eine Sicherheitslücke.
Daher gilt
•
Applets dürfen nicht ohne weiteres auf Dateien des Computers zugreifen
•
Ladezugriffe aus dem Internet sind nur auf den Server zulässig, von dem das Applet
geladen wurde
Der Aufruf eines Applets sieht so aus
<applet code=“HalloWWW.class“ width=“200“ height=“300“>
</applet>
oder so
<applet width="300" height="433" code="Nature.class" align="left"
hspace="20" vspace="12">
<param name="accumulate" value="yes">
<param name="background" value="FFFFFF">
<param name="backimg" value="pixel.gif">
<param name="DeveloperInfo" value="Michael Chancey Jr.">
<param name="speed" value="75">
<param name="foreground" value="FFFFFF">
<param name="graphic" value="winterbild.jpg">
<param name="randomdir" value="yes">
<param name="season" value="winter">
<param name="fallcount" value="400">
</applet>
Ein Applet hat statt dem Haupteinstiegspunkt main() die Methoden init(), start(), paint(),
stop() und destroy().
Diese Methoden werden vom Browser aus gestartet und sind relativ selbsterklärend.
12.2. Der HtmlConverter
Möchte man unabhängig von diversen Browsertypen ein Applet korrekt einbinden, dann findet man
im bin Ordner des JDK ein Programm mit Namen HtmlConverter.exe.
??? Bild
Man gibt hier den Pfad zur HTML Seite an (üblicherweise nach dem Build Befehl im Ordner
build/), und der Rest wird automatisch erledigt!
Der Html Code wird dabei sehr unübersichtlich, liefert aber ein passendes Ergebniss.
12.3. Applets und jar-Dateien
Für größere Projekte oder Datenmengen bietet sich das jar-Format an (vergl. 3.3 Die Struktur der
Dateien). Das ist im Prinzip nichts anderes als ein zip File von allen nötigen Daten. Jar kann von
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -60-
der Konsole aus gestartet werden.
Der Aufruf des Applets sieht dann so aus
<applet code=“HalloWWW.class“ archive=“Pack.jar“ width=“200“
height=“300“></applet>
12.4. Erstellen und testen eines Applets
Möchte man ein komplett neues Projekt eröffnen, oder doch eine bestehende Anwendung in ein
Applet einbinden?
Wir erstellen ein neues Projekt vom Typ Java Class Library.
In der Projektverwaltung erstellen wir mit New → Others erstellen wir in eine
•
Applet Class
•
JApplet Class
•
Japplet Form (hier erhältst du den Form Designer)
etc
So sieht der Projektordner aus.
Wenn du die den Quellcode ansiehst, erkennst du, das es eine Methode init() gibt. Diese Methode
wird vor dem anzeigen des Applets geladen. Daher bereitet man hier alles vor, was für den Betrieb
nötig ist.
public void init() {
/*TODO start asynchronous download of heavy resources*/
}
/*TODO overwrite start(), stop() and destroy() methods*/
Weiters sehen wir hier einen Hinweis auf weitere Methoden des Applets. Diese kann man, wenn
man sie benötigt, überschreiben und verändern.
12.4.1.
Projekteigenschaften erstellen
Bevor wir den ersten Test laufen lassen können, müssen wir noch die Eigenschaften des Projektes
etwas verändern.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -61-
Der Webstart muss so angepasst werden.
Das Allow Offline kann man aktivieren, wenn man möchte.
Wichtig ist die CodeBase, hier muss man den Speicherort am Webserver einstellen! Im Beispiel ist
das http://www.bgbaden-frauen.ac.at/ext/kochapplet/.
12.5. Testen des Projektes
Das Java Network Launching Protocol (JNLP) ist ein XML-Format, das festlegt, wie Anwendungen
per Java Web Start aufgerufen werden. JNLP-Dateien enthalten Informationen wie den Ablageort
von JAR-Dateien, den Namen der Hauptklasse einer Anwendung und zusätzliche Parameter für
das aufzurufende Programm. Ein korrekt konfigurierter Webbrowser übergibt JNLP-Dateien an die
Java-Laufzeitumgebung, die dann ihrerseits die Anwendung auf den PC des Anwenders
herunterlädt und startet.
Zum testen lass die die Files deines Projektes anzeigen.
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -62-
Mit dem Befehl Build F11 lassen wir unser Projekt erstellen.
Im Ordner dist/ erhält man dann das gepackte JAR-File,
das html-Dokument und die *.jnlp Datei.
Optional:
Im bin Ordner des JDK (z.B. C:\Programme\JDK\bin) findet man den HtmlConverter.exe. Mit
dessen Hilfe kann man die HTML Datei noch für alle Browsertypen anpassen.
Man gibt die html-Datei aus dem /dist Ordner an.
12.6. Automatischr Größenanpasseung des Applets an
das Fenster
<body onresize="resize()"
onload="resize()"
topmargin="0"
leftmargin="0"
marginwidth="0"
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -63-
marginheight="0">
<script language="JavaScript" type="text/javascript">
function resize(){
var w_newWidth,w_newHeight;
var w_maxWidth=1600, w_maxHeight=1200;
if (navigator.appName.indexOf("Microsoft") != -1){
w_newWidth=document.body.clientWidth-15;
w_newHeight=document.body.clientHeight-15;
}else{
var netscapeScrollWidth=50;
w_newWidth=window.innerWidth-netscapeScrollWidth;
w_newHeight=window.innerHeight-netscapeScrollWidth;
}
if (w_newWidth>w_maxWidth)
w_newWidth=w_maxWidth;
if (w_newHeight>w_maxHeight)
w_newHeight=w_maxHeight;
document.myApplet.setSize(w_newWidth,w_newHeight);
window.scroll(0,0);
}
window.onResize = resize;
window.onLoad = resize;
</script>
<applet name="myApplet" width="300" height="300">
<param name="jnlp_href" value="launch.jnlp"/>
</applet>
Bufferd Image
http://staff.science.uva.nl/~heck/JAVAcourse/ch6/s2.html
13. Java Documentation erstellen
Mit einem rechten Mausklick auf ein Projekt kann man einen Dokumentation aller Programmteile
anfertigen lassen. Das ist eine gewöhnliche HTML Seite.
Wichtig ist dabei, dass alle Programmteile bereits beim Programmieren dokumentiert wird, und
zwar auf eine bestimmte Art und Weise.
Um die Dokumentation einzuleiten schreibt man
/**
Ein Beispiel könnte so aussehen
/**
* Der Port der Tcp Verbindung
*/
private int port = 0;
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -64-
/**
* Liefert den Port des Servers zurück
* @return port Nummer
*/
public int getPort(){
return port;
}
/**
* Setzt den Port der Serveranwendung
* @param _port Nummer des Ports
*/
public void setPort(int _port){
this.port = _port;
}
14. Virtual Machine steuern
Oft reicht z.B. der reservierte Speicher der VM nicht aus. Dann kann man mit diversen Parametern
die VM steuern.Das passiert bei Netbeans in den Eigenschaften des Projektes
-Xmx1024m.................reserviert 1024 Mbyte für die VM
Eine ausführliche Beschreibung aller Parameter, findest du im Internet!
15. Netzwerkprogrammierung
Wie funktioniert denn das?
Eine gute Anlaufstelle für erste Informationen ist hier
http://download.oracle.com/javase/tutorial/networking/index.html
Im folgenden zeige ich, wie man mit Sockets programmiert. Der Ablauf einer Kommunikation
zwischen Server <> Client sieht so aus
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -65-
Start
Server wartet auf eine
Verbindung mit Client
Client verbindet
sich mit Server
Server verarbeitet
Daten u. sendet
Antwort
Client sendet
Daten
ja
?
Weitere Anfragen
des Clients?
nein
Client beendet
die Verbindung
Die Daten werden zu den Sockets per Streams geschickt. So kannst du z.B. sehr leicht Strings
verschicken, nur was tust du, wenn du String, Integer, Date etc. versenden möchtest?
Wir erstellen uns ein Übermittlungsprotokoll und halten das ein. Und zwar senden wird ByteArrays über die Sockets (in JAVA würde auch Serialisieren mit Object*Streams funktionieren).
15.1. Datenpakete - TcpPackages
Die Kommunikation erfolgt über Datenpakete. Es gelten folgende Bezeichnungen:
GL {4 Bytes}
T
{1 Byte}
D {x Bytes}
... Gesamtlänge des Daten-Paketes
... Typ des Paketes bestimmt
... die Daten
15.2. Paketarten
15.2.1.
Flag – Paket:
(3 Bytes)
PL
F
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -66-
16. SWING und Update von Komponenten
Es stellt sich z.B. das Problem, dass gleichzeitig ein Algorithmus ablaufen, und ein
Fortschittsbalken gezeichnet werden soll.
Man kann dies mit Multithreading, also dem Aufteilen des Programmes in mehrere Prozesse,
erreichen.
Da der Aufbau von Swing (bzw. AWT) es nicht erlaubt, Teile der graphischen Oberfläche in einen
anderen Thread auszulagern, muss man in jedem Fall den Algorithmus auslagern.
Und da Swing nicht threadsicher ist, darf man von dem ausgelagerten Algorithmus eigentlich nicht
auf den Fortschrittsbalken zugreifen!
Ab JRE6 gibt es den SwingWorker, der genau das für uns macht. Hier ein einfaches Beispiel für
einen Label
final JLabel label;
class MeaningOfLifeFinder extends SwingWorker<String, Object> {
@Override
public String doInBackground() {
return findTheMeaningOfLife();
}
@Override
protected void done() {
try {
label.setText(get());
} catch (Exception ignore) {
}
}
}
(new MeaningOfLifeFinder()).execute();
oder
public void Invoke(final String msg, final Color col){
if(output != null){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
output.append(msg, col);
}
});
}
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -67-
17. Zwischenablage und JAVA
Die Zwischenablage ist in Java durch ein Clipboard-Objekt repräsentiert. Es gibt bei grafischen
Oberflächen ein System-Clipboard, welches sich über das Toolkit-Objekt erfragen lässt.
Clipboard systemClip = Toolkit.getDefaultToolkit().getSystemClipboard();
DataFlavor beschreibt das Format der Daten in der Zwischenablage
Die Klasse DataFlavor beschreibt das Format der Daten, die in der Zwischenablage liegen. Die
Klasse kommt neben dem Einsatz in der Zwischenablage auch bei Drag&Drop-Operation und
auch beim Dateisystem vor.
public static void main( String args[] ) throws Exception
{
Clipboard systemClipboard =
Toolkit.getDefaultToolkit().getSystemClipboard();
Transferable transferData = systemClipboard.getContents( null );
DataFlavor dataFlavor[] = transferData.getTransferDataFlavors();
Object content = transferData.getTransferData( dataFlavor[1] );
System.out.println( content );
}
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=412
https://rz-static.unihohenheim.de/anw/programme/prg/java/tutorials/javainsel4/javainsel_15_028.htm#Rxx365java150
28040005531F039100
import java.awt.datatransfer.*;
import java.awt.image.*;
public DataFlavor[] getTransferableDataFlavors() {
Mag. Stefan Hagmann & Mag. Thomas Steiner
JAVA mit Netbeans
Seite -68-
DataFlavors flavors = {DataFlavor.imageFlavor, DataFlavor.stringFlavor};
return flavors;
}
Mag. Stefan Hagmann & Mag. Thomas Steiner
Herunterladen