Grafikprogrammierung in Java

Werbung
Grafikprogrammierung in Java:
Grundlagen
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.1 Grundlagen
11-1
Schnittstellen für Anwenderprogramme
• Eine Schnittstelle für Anwenderprogramme (application programming interface,
API) stellt wohldefinierte und standardisierte Klassen und Methoden zur
Verfügung, die von Anwenderprogrammen genutzt werden können.
• APIs ermöglichen es, vorhandene Software um weitere Funktionen zu ergänzen.
Einige APIs kennen wir ja bereits.
• Java stellt beispielsweise APIs für die folgenden Zwecke zur Verfügung:
◦ Grafikprogrammierung (mit AWT, Swing)
◦ Datenbankzugriffe (mit JDBC)
◦ Netzwerkprogrammierung
◦ Verarbeitung, Auswertung und Transformation von XML-Dokumenten
◦ Verschlüsselung von Daten (Sicherheit, Kryptografie, SecurityManager)
◦ Sound
◦ ...
11.1 Grundlagen
11-2
Grafikprogrammierung
Java bietet den Programmierern zwei Bibliotheken zur Programmierung von
grafischen Benutzeroberflächen (graphical user interface, GUI) an:
• Abstract Window Toolkit (AWT)
Das AWT ermöglicht die Ausführung grundlegender grafischer Operationen. Die
Klassen und Methoden des AWTs sind im Standardpaket java.awt enthalten.
• Swing
Seit der Version 1.1 gibt es eine zweite Grafikbibliothek im Java Development Kit.
Sie heißt Swing und ist Bestandteil des Erweiterungspakets javax.swing. Diese
Bibliothek beseitigt etliche Schwächen des AWTs und bietet eine weitgehend
plattformunabhängige Schnittstelle. Die Möglichkeiten, die Swing bietet,
übersteigen die des AWTs.
11.1 Grundlagen
11-3
Grafikprogrammierung
Neben AWT und Swing gibt es eine verbreitete Bibliothek zur Programmierung
grafischer Benutzeroberflächen:
• Standard Widget Toolkit (SWT)
SWT ist eine Bibliothek für die Erstellung grafischer Oberflächen mit Java. Sie
wurde im Jahr 2001 von IBM für die Entwicklungsumgebung Eclipse entwickelt
und kommt in einer ganzen Reihe von Anwendungen zum Einsatz, beispielsweise
Eclipse selbst. SWT leidet auf einigen Nicht-Windows-Plattformen unter
Effizienzproblemen. SWT gehört nicht zum JDK.
Wir gehen hier (aus Zeitgründen) nicht auf SWT ein. Es gibt weitere Bibliotheken.
11.1 Grundlagen
11-4
Das Abstract Window Toolkit
Die Fähigkeiten des AWTs lassen sich in vier Gruppen einteilen:
• Grundoperationen zum Zeichnen von Linien und Flächen und zur Ausgabe von Text
• Methoden zur Programmsteuerung durch die Behandlung von Maus-, Tastaturund Fensterereignissen
• Dialogelemente zur Kommunikation mit dem Anwender
• Fortgeschrittene Operationen zur Ausgabe von Bitmaps und Tönen
11.1 Grundlagen
11-5
Ein einführendes Beispiel
import java.awt.*;
public class Fenster extends Frame {
Fenster() {
setBackground(Color.yellow);
setSize(200,150);
setLocation(500,500);
setVisible(true);
}
public static void main(String[] args) {
new Fenster();
}
}
11.1 Grundlagen
11-6
Das Abstract Window Toolkit
• Zum Ableiten einer eigenen Fensterklasse wird in der Regel entweder die Klasse
Frame oder die Klasse Dialog verwendet.
• Um ein neues Fenster zu erhalten, muss ein Objekt der Klasse Frame erzeugt, auf
die gewünschte Größe gebracht und durch Aufruf der Methode setVisible
sichtbar gemacht werden.
• Die Ausgabe in ein Fenster erfolgt durch Überlagern der Methode paint. Diese
Methode wird immer dann aufgerufen, wenn das Fenster neu gezeichnet werden
muss, z. B. beim Programmstart oder beim Verändern der Größe.
• Die Methode void paint(Graphics g) erhält als Parameter einen grafischen
Kontext. Hierunter versteht man allgemeine Einstellungen für Schrift und Grafik,
beispielsweise den aktuellen Font und die aktuelle Farbe.
11.1 Grundlagen
11-7
Ein einführendes Beispiel
import java.awt.*;
class Rechteck extends Canvas {
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(20,20,100,40);
g.setColor(Color.black);
g.drawString("Ein rotes Rechteck",20,80);
setLocation(20,15);
}
}
// Vokabeltest: canvas = Leinwand
11.1 Grundlagen
11-8
class EinfachesFenster extends Frame {
EinfachesFenster() {
add(new Rechteck());
setBackground(Color.yellow);
setSize(200,150);
setVisible(true);
setLocation(200,200);
}
public static void main(String[] args) {
new EinfachesFenster();
}
}
11.1 Grundlagen
11-9
Ereignisgesteuerte Programmierung
• Die Programme, die wir bisher betrachtet haben, arbeiten nach dem Prinzip der
Ein-Ausgabe-Programmierung.
• Dieses Modell wird jetzt zur ereignisgesteuerten Programmierung erweitert.
Ereignisse sind beispielsweise das Drücken einer Taste, die Betätigung des
Rollbalkens oder die Bewegung der Maus.
• Es gibt viele Varianten der ereignisgesteuerten Programmierung. In Java wird das
sogenannte Delegation Based Event Handling verwendet. Es bietet die Möglichkeit,
GUI-Ereignisse an beliebige Objekte weiterzuleiten und dort zu behandeln. Auf
diese Weise können die Oberfläche und die eigentliche Anwendung klar
voneinander getrennt werden.
11.1 Grundlagen
11-10
Ereignisgesteuerte Programmierung
• Jedes Ereignis besitzt eine Quelle (Source). Ein Ereignis kann von Beobachtern
(Listener) wahrgenommen werden. Die Anmeldung von Beobachtern zur
Benachrichtigung vom Eintreten eines Ereignisses ist frei programmierbar und muss
immer explizit erfolgen.
• Es ist nicht festgelegt, in welcher Reihenfolge die Beobachter vom Eintreten eines
Ereignisses informiert werden. Sichergestellt ist lediglich, dass jeder Beobachter
eine Kopie des ursprünglichen Ereignisses erhält.
• Bei der Verbreitung von Ereignissen ist zwischen den Modi single-cast und
multi-cast zu unterscheiden. Für Single-Cast-Ereignisse wird der Beobachter mit
einer setxxListener-Methode gesetzt, für Multi-Cast-Ereignisse wird ein
Beobachter mit einer addxxListener-Methode der Menge der Beobachter
hinzugefügt.
11.1 Grundlagen
11-11
Beispiel: Schließen eines Fensters
• Um ein Fenster zu schließen, muss ein WindowListener registriert werden.
• Hierbei handelt es sich um einen Beobachter, dessen Methode windowClosing
aufgerufen wird, wenn der Anwender das Fenster über ein System-Menü oder einen
Button schließen möchte.
• Das Fenster wird durch setVisible(false) unsichtbar gemacht, seine
Ressourcen durch dispose() wieder freigegeben.
11.1 Grundlagen
11-12
Beispiel: Schließen eines Fensters
import java.awt.*;
import java.awt.event.*;
public class WindowClosingAdapter extends WindowAdapter {
public void windowClosing(WindowEvent event) {
event.getWindow().setVisible(false);
event.getWindow().dispose();
System.out.println("Das Fenster wurde geschlossen!");
}
}
Frame wnd = new Frame();
wnd.addWindowListener(new WindowClosingAdapter());
wnd.setSize(400,300);
wnd.setVisible(true);
11.1 Grundlagen
11-13
Adapter-Klassen
• Eine Adapter-Klasse ist eine Klasse, die eine gegebene Schnittstelle implementiert,
indem sie jede abstrakte Methode durch einen leeren Rumpf realisiert.
• Adapter-Klassen werden verwendet, wenn von einer Schnittstelle lediglich ein Teil
der Methoden benötigt wird, der Rest aber uninteressant ist. In diesem Fall leitet
man eine neue Klasse aus der Adapter-Klasse ab und überlagert nur die
erforderlichen Methoden.
• Beispiel: Die Klasse WindowAdapter implementiert die Schnittstellen
WindowListener, WindowStateListener und WindowFocusListener durch
leere Rümpfe. Hierbei handelt es sich um die folgenden Methoden:
11.1 Grundlagen
11-14
Die Klasse WindowAdapter
void
void
void
void
void
void
void
void
void
void
windowActivated(WindowEvent e)
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowDeactivated(WindowEvent e)
windowDeiconified(WindowEvent e)
windowGainedFocus(WindowEvent e)
windowIconified(WindowEvent e)
windowLostFocus(WindowEvent e)
windowOpened(WindowEvent e)
windowStateChanged(WindowEvent e)
11.1 Grundlagen
11-15
Ein einführendes Beispiel
Wir fassen zusammen:
import java.awt.*;
import java.awt.event.*;
class WindowClosingAdapter extends WindowAdapter {
public void windowClosing(WindowEvent event) {
event.getWindow().setVisible(false);
event.getWindow().dispose();
System.out.println("Das Fenster wurde geschlossen!");
}
}
11.1 Grundlagen
11-16
class Rechteck extends Canvas {
public void paint(Graphics g) {
g.setColor(Color.red);
g.fillRect(20,20,100,40);
g.setColor(Color.black);
g.drawString("Ein rotes Rechteck",20,80);
setLocation(20,15);
}
}
11.1 Grundlagen
11-17
public class EinfachesFenster extends Frame {
EinfachesFenster(String title) {
super(title);
addWindowListener(new WindowClosingAdapter());
setBackground(Color.yellow);
setSize(400,200);
add(new Rechteck());
setVisible(true);
}
}
11.1 Grundlagen
11-18
EinfachesFenster e1 = new EinfachesFenster("Erstes Fenster"),
e2 = new EinfachesFenster("Zweites Fenster"),
e3 = new EinfachesFenster("Drittes Fenster");
e1.setLocation(200,200);
e2.setLocation(400,300);
e3.setLocation(600,400);
11.1 Grundlagen
11-19
Grafikprogrammierung in Java:
Grafische Grundelemente
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.2 Grafische Grundelemente
11-20
Das grafische Koordinatensystem
• Die Ausgabe von grafischen Objekten basiert auf einem zweidimensionalen
Koordinatensystem, dessen Ursprung (0,0) in der linken oberen Ecke liegt.
x
?
y
• Positive x-Werte erstrecken sich nach rechts, positive y-Werte nach unten. Die
Maßeinheit entspricht einem Bildschirmpixel und ist somit geräteabhängig.
11.2 Grafische Grundelemente
11-21
Der Benutzerbereich
• Es steht nicht das gesamte Fenster für Ausgaben zur Verfügung. Oben, unten,
links und rechts wird Platz zur Ausgabe von Rahmen und Titelzeile benötigt.
• Mit
◦ getSize().width und getSize().height
kann die Gesamtbreite bzw. -höhe eines Fensters ermittelt werden. Durch
◦ getInsets().left, getInsets().right, getInsets().top und
getInsets().bottom
lässt sich die Abmessung des Rahmens und durch Differenzbildung die des
Benutzerbereichs (client area) bestimmen.
11.2 Grafische Grundelemente
11-22
Elementare Grafikroutinen (Auswahl)
• void drawString(String s, int x, int y)
drawString schreibt den String s an die Position (x,y). Diese Koordinaten stellen
das linke Ende der Basislinie von s dar.
• void drawChars(char[] c, int offset, int length, int x, int y)
Diese Methode schreibt ein Zeichenfeld. Die Parameter offset und length
können zur Angabe des ersten Zeichens und der Anzahl der auszugebenden
Zeichen verwendet werden.
11.2 Grafische Grundelemente
11-23
Elementare Grafikroutinen (Auswahl)
Beispiel: Die Anweisungen
char[] c = {’a’,’b’,’c’,’d’,’e’,’f’};
g.drawString("Zeichenkette",50,50);
g.drawChars(c,1,4,50,150);
schreiben den String "Zeichenkette" an die Position (50,50) und darunter die Zeichen
"bcde" an die Position (50,150).
11.2 Grafische Grundelemente
11-24
Elementare Grafikroutinen (Auswahl)
• void drawLine(int x1, int y1, int x2, int y2)
Diese Methode zieht eine Linie von der Position (x1,y1) zur Position (x2,y2).
• void drawRect(int x, int y, int width, int height)
drawRect zeichnet ein Rechteck der Breite width und der Höhe height, dessen
linke obere Ecke an der Position (x,y) liegt.
• void drawRoundRect(int x, int y, int width, int height, int
arcWidth, int arcHeight)
Es wird ein Rechteck mit abgerundeten Ecken gezeichnet. arcWidth und
arcHeight bestimmen die Halbachsen der Ellipse, die zur Darstellung der Ecken
verwendet wird.
11.2 Grafische Grundelemente
11-25
Elementare Grafikroutinen (Auswahl)
• void drawPolygon(int[] x, int[] y, int anzahl)
Diese Methode zeichnet einen Linienzug. Die x-Koordinaten der Punkte werden
dem ersten Parameter, die y-Koordinaten dem zweiten Parameter entnommen. Die
Anzahl der Koordinatenpaare wird durch den dritten Parameter festgelegt. Der
Polygonzug wird geschlossen. Durch drawPolyline kann ein nichtgeschlossener
Linienzug dargestellt werden.
Eine andere Möglichkeit, ein Polygon zu erzeugen, besteht darin, einen Konstruktor
der Klasse Polygon aufzurufen:
• Polygon(int[] x, int[] y, int anzahl)
Polygon()
Durch addPoint kann ein Polygon erweitert werden.
11.2 Grafische Grundelemente
11-26
Elementare Grafikroutinen (Auswahl)
• void drawOval(int x, int y, int width, int height)
Mit dieser Methode können Kreise und Ellipsen gezeichnet werden. Die Parameter
spezifizieren ein Rechteck wie in der Methode drawRect. Es wird die größte
Ellipse gezeichnet, die in dieses Rechteck hineinpasst.
• void drawArc(int x, int y, int width, int height, int
startAngle, int arcAngle)
Mit drawArc kann ein Kreisbogen dargestellt werden. Die ersten vier Parameter
geben den Kreis, startAngle den Anfangswinkel und arcAngle den Winkel an.
11.2 Grafische Grundelemente
11-27
Elementare Grafikroutinen (Auswahl)
Die folgenden Funktionen stellen die gleichen geometrischen Objekte dar wie die
obigen, zeichnen aber nicht nur deren Umrisse, sondern füllen auch ihre Fläche aus.
• void fillRect( ... )
• void fillRoundRect( ... )
• void fillPolygon( ... )
• void fillOval( ... )
• void fillArc( ... )
11.2 Grafische Grundelemente
11-28
Elementare Grafikroutinen (Auswahl)
• void clearRect(int x, int y, int width, int height)
Die Methode clearRect überschreibt das angegebene Rechteck mit der aktuellen
Hintergrundfarbe.
• void copyArea(int x, int y, int width, int height, int dx, int
dy)
copyArea kopiert das ausgewählte Rechteck an die Position (x + dx, y + dy).
• Mit einer Clipping-Region kann die Ausgabe auf einen bestimmten Bereich
eingeschränkt werden.
11.2 Grafische Grundelemente
11-29
Schriftarten
• Ohne zusätzliche Anweisungen wird Text in einem systemabhängigen
Standard-Font ausgegeben. Um einen anderen Font zur Textausgabe zu
verwenden, muss zuerst ein Font-Objekt erzeugt und dann in den Grafik-Kontext
eingetragen werden.
• Ein Font-Objekt kann mit einem Konstruktor der Klasse Font erzeugt werden:
Font(String name, int style, int size)
• Mit
void setFont(Font font) und
Font getFont()
kann der Font gesetzt bzw. abgefragt werden.
11.2 Grafische Grundelemente
11-30
Schriftarten
• Der Parameter name gibt den Namen der gewünschten Schrift an. Font-Namen
sind beispielsweise Times New Roman, Helvetica oder Courier.
• Schriften können Serifen besitzen oder auch serifenlos sein.
• Ein weiteres Kennzeichen einer Schrift ist die Zeichenbreite. Diese kann variabel
oder konstant sein. Bei konstanter Zeichenbreite bezeichnet man eine Schrift als
monospaced.
• Beispiel: Der Font, in dem diese Folien geschrieben wurden, ist die serifenlose
Variante der „Latin Computer Modern“.
• Es können auch die Font-Namen Serif, SansSerif und Monospaced verwendet
werden. Sie werden auf entsprechende Fonts abgebildet.
11.2 Grafische Grundelemente
11-31
Schriftarten
• Der Parameter size gibt die Schriftgröße an. Übliche Schriftgrößen für Text liegen
zwischen 10 pt und 12 pt.
• Die Schriftart wird durch den Parameter style beschrieben:
Name
Font.PLAIN
Font.BOLD
Font.ITALIC
11.2 Grafische Grundelemente
Wert
0
1
2
3
Bedeutung
Standard-Font
Fettdruck
Kursivdruck
fetter Kursivdruck
11-32
Schriftarten
Beispiel: Die folgenden Anweisungen bewirken, dass der String "Zeichenkette" in einer
Schrift mit konstanter Zeichenbreite in fettem Kursivdruck in 12-Punkt-Schrift an die
Position (50,350) geschrieben wird:
Font f = new Font("Monospaced",3,12);
g.setFont(f);
g.drawString("Zeichenkette",50,350);
11.2 Grafische Grundelemente
11-33
Schriftarten
Das folgende Beispiel gibt die drei Standardschriften in 36 Punkt aus:
public void paint(Graphics g) {
Font font;
String[] arfonts = {"Serif","SansSerif","Monospaced"};
for (int i = 0; i < arfonts.length; ++i) {
font = new Font(arfonts[i],Font.PLAIN,36);
g.setFont(font);
g.drawString(arfonts[i],10,30 + (i + 1) * (36 + 5));
}
}
11.2 Grafische Grundelemente
11-34
Schriftarten
• Die Klasse Font besitzt Methoden, um Informationen über den aktuellen Font zu
gewinnen:
◦ String getFamily()
◦ int getStyle()
◦ int getSize()
• Die Klasse FontMetrics stellt Methoden zur Verfügung, mit denen die
Größenmaßzahlen einzelner Zeichen – wie Oberlänge, Unterlänge oder Breite –,
Größen wie der Zeilenabstand oder die Länge eines Strings ermittelt werden
können.
◦ int charWidth(char ch)
◦ int stringWidth(String str)
11.2 Grafische Grundelemente
11-35
Farbmodell
Eine Möglichkeit, in Java Farben zu
benutzen, basiert auf dem RGB-Farbmodell
(Rot-Grün-Blau-Farbmodell). Jede dieser
drei Grundfarben wird durch 8 Bits
dargestellt. Der Anteil einer Grundfarbe
kann also durch eine Dezimalzahl zwischen
0 und 255 beschrieben werden. Für die
gesamte Farbtiefe ergeben sich somit 24
Bits.
Farbe
Weiß
Grau
Schwarz
Rot
Grün
Blau
Gelb
Magenta
Cyan
Rot
255
127
0
255
0
0
255
255
0
Grün
255
127
0
0
255
0
255
0
255
Blau
255
127
0
0
0
255
0
255
255
Java unterstützt weitere Farbmodelle, in denen Farben z. B. durch Farbton, Intensität
und Helligkeit dargestellt werden.
11.2 Grafische Grundelemente
11-36
Erzeugung von Farben
• Farben werden durch die Klasse Color dargestellt. Jedes Objekt repräsentiert eine
Farbe, die durch ihren RGB-Wert eindeutig gekennzeichnet ist.
• Konstruktoren:
◦ Color(int r, int g, int b)
◦ Color(float r, float g, float b)
Der erste Konstruktor erwartet ganzzahlige Werte im Bereich von 0 bis 255, der
zweite Fließkommazahlen zwischen 0.0 und 1.0. Der Wert 0.0 entspricht der
ganzzahligen 0, der Wert 1.0 der ganzzahligen 255.
11.2 Grafische Grundelemente
11-37
Erzeugung von Farben
• Die Klasse Color stellt etliche Farben als statische Objekte zur Verfügung:
◦
◦
◦
◦
◦
static
static
static
static
...
Color
Color
Color
Color
black
red
green
blue
• Von einem bestehenden Farbobjekt kann der RGB-Wert mit den Methoden
◦ int getRed(),
◦ int getGreen() und
◦ int getBlue()
ermittelt werden.
11.2 Grafische Grundelemente
11-38
Verwendung von Farben
• Um Farben bei der Ausgabe von Schrift oder Grafik zu verwenden, muss ein Objekt
der Klasse Color erzeugt und mithilfe der Methode
void setColor(Color c)
dem grafischen Kontext zugewiesen werden.
• Die Ausgabe erfolgt solange in der neuen Farbe, bis dem Kontext eine neue Farbe
zugeordnet wird.
• Mit Color getColor() wird die aktuelle Farbe abgefragt.
11.2 Grafische Grundelemente
11-39
Verwendung von Farben
Beispiel:
public void paint(Graphics g) {
g.setColor(Color.red);
g.drawString("Zeichenkette",200,500);
g.setColor(new Color(200,200,0));
g.drawOval(50,400,60,160);
...
}
11.2 Grafische Grundelemente
11-40
Die Klasse SystemColor
• Die Klasse SystemColor stellt eine Reihe von Farben zur Verfügung, die den
Farben des Desktops entsprechen. Damit können Anwendungen entwickelt werden,
die im Aussehen an die Betriebssystemumgebung angepasst sind.
• Beispiele:
◦ SystemColor.desktop
Hintergrundfarbe des Desktops
◦ SystemColor.window
Hintergrundfarbe für Fenster
◦ SystemColor.text
Hintergrundfarbe für Text
11.2 Grafische Grundelemente
11-41
Grafikprogrammierung in Java:
Fensterklassen
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.3 Fensterklassen
11-42
Fensterklassen
Das AWT enthält eine Reihe von Fensterklassen, die über eine Vererbungslinie
miteinander verbunden sind. An der Spitze steht die Klasse Component:
• Component
◦ Container
∗ Panel
- Applet
∗ Window
- Frame
- Dialog
· FileDialog
11.3 Fensterklassen
◦
◦
◦
◦
◦
◦
◦
◦
Button
Canvas
Checkbox
Choice
Label
List
Scrollbar
Textcomponent
11-43
Fensterklassen
• Component ist eine abstrakte Klasse, deren Objekte Programmelemente darstellen,
die eine Größe und eine Position besitzen und die Ereignisse senden und auf
Ereignisse reagieren können.
• Container ist eine konkrete Klasse. Sie erlaubt es, innerhalb einer Komponente
weitere Komponenten aufzunehmen. Container stellt Methoden, um
Komponenten hinzuzufügen oder zu entfernen, bereit. Mit den
LayoutManager-Klassen werden die Komponenten positioniert.
• LayoutManager, LayoutManager2 sind Interfaces. Implementierende Klassen sind
beispielsweise BorderLayout, FlowLayout, GridLayout, . . .
11.3 Fensterklassen
11-44
Fensterklassen
• Panel ist die einfachste konkrete Klasse mit den Eigenschaften von Component
und Container.
• Applet ist eine direkte Unterklasse von Panel. Ein Applet besitzt also die
Fähigkeiten der Klassen Component und Container. Diese Klasse spielt eine
entscheidende Rolle in der Entwicklung von Applets.
• Die Klasse Window abstrahiert ein Top-Level-Window ohne Rahmen, Titelleiste
und Menü. Sie ist für Anwendungen geeignet, die die Kontrolle über das gesamte
Fenster benötigen.
• Frame repräsentiert ein Top-Level-Window mit Rahmen, Titelleiste und
optionalem Menü. Einem Frame kann ein Icon zugeordnet werden, das angezeigt
wird, wenn ein Fenster minimiert wird.
11.3 Fensterklassen
11-45
Aufrufen und Schließen eines Fensters
• Um ein Fenster auf dem Bildschirm anzuzeigen, muss zunächst eine geeignete
Fensterklasse instanziiert werden. Dafür kommen Klassen wie Window, Frame,
Dialog, Applet und FileDialog in Frage. Die Klassen haben unterschiedliche
Konstruktoren.
• Nach der Instanziierung wird die Methode
setVisible(boolean visible)
aufgerufen, um das Fenster anzuzeigen. Wird true übergeben, wird das Fenster
angezeigt, andernfalls geschlossen.
• Um ein Fenster zu schließen, sind die Methoden setVisible(false) und
dispose() aufzurufen.
11.3 Fensterklassen
11-46
Eigenschaften eines Fensters
• Größe und Position, geerbt von Component
• Aktivierungskomponente, geerbt von Component
• Fensterelemente
◦ Titelleiste, Menü, Icon, Mauscursor, Standardfont, Vorder- und Hintergrundfarbe
• Die Eigenschaften eines Fensters können mithilfe spezieller Methoden gesetzt und
abgefragt werden.
• Beispiel: Objekte der Klasse Frame besitzen einen Rahmen, eine Titelleiste und
optional ein Menü, Objekte der Klasse Window hingegen nicht.
11.3 Fensterklassen
11-47
Grafikprogrammierung in Java:
Ereignisse und Widgets
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.4 Ereignisse und Widgets
11-48
Ereignisgesteuerte Programmierung
• Ereignisse sind beispielsweise das Drücken einer Taste, die Betätigung des
Rollbalkens oder die Bewegung der Maus.
• Jedes Ereignis besitzt eine Quelle (Source).
• Ein Ereignis kann von Beobachtern (Listener) wahrgenommen werden. Die
Anmeldung von Beobachtern zur Benachrichtigung vom Eintreten eines Ereignisses
ist frei programmierbar und muss immer explizit erfolgen.
• Es ist nicht festgelegt, in welcher Reihenfolge die Beobachter vom Eintreten eines
Ereignisses informiert werden. Sichergestellt ist lediglich, dass jeder Beobachter
eine Kopie des ursprünglichen Ereignisses erhält.
11.4 Ereignisse und Widgets
11-49
Ereignisgesteuerte Programmierung
• Bei der Verbreitung von Ereignissen ist zwischen den Modi single-cast und
multi-cast zu unterscheiden. Für Single-Cast-Ereignisse wird der Beobachter mit
einer setxxListener-Methode gesetzt, für Multi-Cast-Ereignisse wird ein
Beobachter mit einer addxxListener-Methode der Menge der Beobachter
hinzugefügt.
• Eine Adapter-Klasse ist eine Klasse, die eine gegebene Schnittstelle implementiert,
indem sie jede abstrakte Methode durch einen leeren Rumpf realisiert.
Adapter-Klassen werden verwendet, wenn von einer Schnittstelle lediglich ein Teil
der Methoden benötigt wird, der Rest aber uninteressant ist. In diesem Fall leitet
man eine neue Klasse aus der Adapter-Klasse ab und überlagert nur die
erforderlichen Methoden.
11.4 Ereignisse und Widgets
11-50
Ereignisklassen
• EventObject
◦ AWTEvent
∗ ComponentEvent
- FocusEvent
- InputEvent
- KeyEvent
- MouseEvent
- ContainerEvent
- WindowEvent
∗ ActionEvent
∗ AdjustmentEvent
∗ ItemEvent
∗ TextEvent
11.4 Ereignisse und Widgets
11-51
EventListener-Schnittstellen
• EventListener
◦
◦
◦
◦
◦
◦
◦
◦
◦
◦
◦
FocusListener
ActionListener
AdjustmentListener
ItemListener
TextListener
KeyListener
MouseListener
MouseMotionListener
WindowListener
ContainerListener
ComponentListener
11.4 Ereignisse und Widgets
11-52
Low-Level-Events
Beispiel: Window-Events
• windowOpened
• windowActivated, windowDeactivated
• windowClosed
• windowClosing
• windowIconified, windowDeiconified
11.4 Ereignisse und Widgets
11-53
Widgets
Fensterelemente mit Ein- und/oder Ausgabefunktionalität werden als Widgets
(window gadgets) bezeichnet. Die Anordnung der Widgets in einem Fenster wird
durch den Layout-Manager durchgeführt. Widgets sind beispielsweise:
• Label
• Rollbalken
• Schaltflächen (buttons)
• Checkboxen und Checkboxgruppen (radio buttons)
11.4 Ereignisse und Widgets
11-54
Widgets
• Textfelder und Textbereiche
• Auswahlboxen
• Listen
• Canvas
• Panels
• Dateidialogboxen (nicht für Applets)
• Menüs (nicht für Applets)
11.4 Ereignisse und Widgets
11-55
Schritte zur Realisierung eines Widgets
• Schnittstelle angeben
• Widget deklarieren und initialisieren
• Widget dem Layout hinzufügen
• Beobachter registrieren
• Ereignis behandeln
Man beachte, dass mehrere Widgettypen dieselbe Ereignisklasse verwenden, z. B.
benutzen Schaltflächen und Textfelder die Klasse ActionListener.
11.4 Ereignisse und Widgets
11-56
Beispiel: Rollbalken
Als erstes Beispiel betrachten wir jetzt die Programmierung eines Rollbalkens.
import java.awt.*;
import java.awt.event.*;
public class WindowBlind extends Frame
implements AdjustmentListener {
private Scrollbar schieber;
private int schieberWert;
11.4 Ereignisse und Widgets
11-57
public WindowBlind() {
setLayout(new FlowLayout());
setBackground(Color.white);
schieber = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,101);
add(schieber);
addWindowListener(new WindowClosingAdapter());
schieber.addAdjustmentListener(this);
}
11.4 Ereignisse und Widgets
11-58
public void paint(Graphics g) {
g.drawString("Rollbalkenwert ist " + schieberWert,120,200);
g.setColor(Color.red);
g.drawRect(40,80,60,100);
g.fillRect(40,80,60,schieberWert);
g.setColor(Color.blue);
g.drawRect(120,80,60,100);
g.fillRect(120,80 + schieberWert,60,100 - schieberWert);
g.setColor(Color.green);
g.drawRect(200,80,60,100);
g.fillRect(200,80,60,100 - schieberWert);
}
11.4 Ereignisse und Widgets
11-59
public void adjustmentValueChanged(AdjustmentEvent e) {
schieberWert = schieber.getValue();
repaint();
}
11.4 Ereignisse und Widgets
11-60
public static void main(String[] args) {
WindowBlind f = new WindowBlind();
f.setSize(400,300);
f.setVisible(true);
}
}
11.4 Ereignisse und Widgets
11-61
Beispiel: Label und Button
... implements ActionListener {
private Label title;
private Button knopf1, knopf2;
private int anzahl = 0;
public Konstruktor() {
setLayout(new FlowLayout());
title = new Label("Zählknopf:");
knopf1 = new Button("Drück mich!");
knopf2 = new Button("Ende");
add(title); add(knopf1); add(knopf2);
knopf1.addActionListener(this);
knopf2.addActionListener(this);
}
11.4 Ereignisse und Widgets
11-62
public void paint(Graphics g) {
g.drawString("Der Knopf wurde " + anzahl +
" mal gedrückt.",10,80);
}
public void actionPerformed(ActionEvent event) {
anzahl++;
if (event.getSource() == knopf2) System.exit(0);
repaint();
}
}
11.4 Ereignisse und Widgets
11-63
AbstractButton
• Die abstrakte Klasse AbstractButton ist eine Unterklasse der Klasse
JComponent (s. Abschnitt Swing-Klassen).
• Die abstrakte Klasse AbstractButton enthält die Methode void doClick()
durch die in Implementierungen dieser Klasse ein Klick programmatisch ausgeführt
werden kann.
• Beispiele für Unterklassen von AbstractButton sind die Klassen JButton,
JToggleButton und JMenuItem.
11.4 Ereignisse und Widgets
11-64
Weitere Widgets
• Textfield:
ActionListener, addActionListener
void actionPerformed(ActionEvent event)
• Checkbox, Checkboxgroup:
ItemListener, addItemListener
void itemStateChanged(ItemEvent event)
• Choice:
ItemListener, addItem, addItemListener
void itemStateChanged(ItemEvent event)
11.4 Ereignisse und Widgets
11-65
Grafikprogrammierung in Java:
Applets
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.5 Applets
11-66
Anwendungen und Applets
• Anwendungen (Applikationen)
◦ Anwendungen bilden eigenständige Programme. Zur Ausführung benötigen sie
nur den Java-Interpreter und die .class-Dateien der beteiligten Klassen.
◦ Jede Klasse, die die Methode public static void main enthält, kann als
Anwendung benutzt werden.
• Applets (little applications)
◦ Applets sind kleine Programme, die in eine Html-Seite eingebettet sind und nur
innerhalb eines Web-Browsers oder eines Applet-Viewers ausgeführt werden
können.
◦ Applets werden nicht durch die Methode main gestartet, sondern müssen aus
der Klasse Applet abgeleitet und entsprechend konstruiert werden.
11.5 Applets
11-67
Ein kleines Applet: Java-Datei
import java.awt.*;
import java.applet.*;
public class MinimalApplet extends Applet {
public void paint(Graphics g) {
g.drawString("Test-Ausgabe",0,20);
}
}
11.5 Applets
11-68
Ein kleines Applet: Html-Seite
<html>
<head>
<title>Applet-Test</title>
</head>
<body>
<applet code="MinimalApplet" width=600 height=800>
Hier steht das Applet.</applet>
</body>
</html>
11.5 Applets
11-69
Anwendungen und Applets
• Ein Applet wird immer aus der Klasse Applet abgeleitet. Bei einer Anwendung ist
es dagegen gleichgültig, woraus die Hauptklasse abgeleitet wird.
• Eine Anwendung wird gestartet, indem vom Java-Interpreter die Methode main
aufgerufen wird. Das Starten eines Applets wird dadurch erreicht, dass der Browser
oder der Applet-Viewer die Applet-Klasse instanziiert und die Methoden init und
start aufruft.
• Aus Gründen der Sicherheit darf ein Applet in der Regel weder auf Dateien des
lokalen Rechners zugreifen noch externe Programme auf dem Rechner starten.
11.5 Applets
11-70
Anwendungen und Applets
• Ein Applet arbeitet immer ereignisorientiert. Im Gegensatz dazu kann eine
Anwendung auf die Behandlung von Ereignissen verzichten und alle Ein- und
Ausgaben textbasiert durchführen.
• Im Vergleich zu Anwendungen bieten Applets einige zusätzliche Möglichkeiten.
11.5 Applets
11-71
Die Klasse Applet
Die Klasse Applet steht in der Vererbungshierarchie unter der Klasse Component
und Container. Sie besitzt damit deren Eigenschaften.
• Component
◦ Container
∗ Panel
- Applet
Bezüglich der Reaktion auf Ereignisse und die Registrierung und Programmierung von
Listener-Klassen verhält sich ein Applet wie jedes andere Fenster.
11.5 Applets
11-72
Methoden
• init(): Initialisierung eines Applets
• start(): Start eines Applets
• stop(): Stopp eines Applets,
z. B. beim Laden einer anderen Seite.
start und stop können mehrfach während der Lebensdauer eines Applets
aufgerufen werden.
• paint(Graphics g): Methode zum Zeichnen
• destroy(): Beenden eines Applets
11.5 Applets
11-73
Beispiel: Rollbalken
Als Beispiel schreiben wir das Rollbalkenprogramm als Applet.
import java.awt.*;
import java.awt.event.*;
import java.applet.Applet;
public class WindowBlind extends Applet
implements AdjustmentListener {
private Scrollbar schieber;
private int schieberWert;
11.5 Applets
11-74
public void init () {
setBackground(Color.white);
schieber = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,101);
add(schieber);
schieber.addAdjustmentListener(this);
}
11.5 Applets
11-75
public void paint(Graphics g) {
showStatus("Rollbalkenwert ist " + schieberWert);
g.setColor(Color.red);
g.drawRect(40,80,60,100);
g.fillRect(40,80,60,schieberWert);
g.setColor(Color.blue);
g.drawRect(120,80,60,100);
g.fillRect(120,80 + schieberWert,60,100 - schieberWert);
g.setColor(Color.green);
g.drawRect(200,80,60,100);
g.fillRect(200,80,60,100 - schieberWert);
}
11.5 Applets
11-76
public void adjustmentValueChanged(AdjustmentEvent e) {
schieberWert = schieber.getValue();
repaint();
}
}
11.5 Applets
11-77
Anwendungen und Applets
Dies sind die wesentlichen Schritte, um eine Anwendung in ein Applet zu konvertieren.
Die Anwendung darf nur Elemente benutzen, die auch für Applets erlaubt sind.
• Html-Seite erzeugen
• main-Methode löschen
• Aus dem Paket java.applet importieren, JApplet statt JFrame erweitern
• Konstruktor in init umbenennen, ggf. start, stop, destroy schreiben
• Layout festlegen
• Bei mehreren Klassen: jar-Datei erzeugen
11.5 Applets
11-78
Anwendungen und Applets
Dies sind die wesentlichen Schritte, um ein Applet in eine Anwendung zu konvertieren.
Das Applet darf keine speziellen Methoden der applet-Klasse verwenden.
• import applet löschen
• frame statt applet erweitern
• init als Konstruktor schreiben
• main-Methode erzeugen
• Methode zum Fenster schließen hinzufügen
• Layout festlegen
11.5 Applets
11-79
Grafikprogrammierung in Java:
Die Swing-Klassen
11.1
11.2
11.3
11.4
11.5
11.6
Grundlagen
Grafische Grundelemente
Fensterklassen
Ereignisse und Widgets
Applets
Die Swing-Klassen
11.6 Die Swing-Klassen
11-80
Die Java Foundation Classes
Seit der Version 1.2 des JDK werden die grafischen Fähigkeiten von Java unter dem
Begriff Java Foundation Classes (JFC) zusammengefasst. Die drei wichtigsten
Bestandteile sind:
• Das Abstract Window Toolkit (AWT) stellt elementare Grafik- und
Fensterfunktionen auf der Basis der jeweiligen Zielmaschine zur Verfügung.
• Das Swing Toolset bietet darüber hinausgehende Möglichkeiten zur Konstruktion
komplexer grafischer Oberflächen. Insbesondere wird ein „pluggable look and feel“
ermöglicht.
• Die dritte wichtige Komponente ist die Java 2D API (Klassen für zweidimensionale
Grafikverarbeitung) mit diversen Grafikoperationen und Bildbearbeitungsroutinen.
11.6 Die Swing-Klassen
11-81
Die Java Foundation Classes
Die Klassen lassen sich in vier Gruppen einteilen:
• Behälter (container) bestehen aus Komponenten, die auch selbst Komponenten
enthalten können. Beispielsweise sind die Objekte der Klassen JFrame und
JWindow Behälter.
• Komponenten enthalten die Bestandteile der Fenster. Komponenten sind
beispielsweise Beschriftungen (label), Auswahlfelder, Knöpfe (buttons), . . .
• Layout-Manager, Fonts und Farben bestimmen die Anordnung und das Aussehen
der Komponenten in einem Behälter.
• Mit den Ereignisklassen werden mögliche Ereignisse, Beobachter und Reaktionen
festgelegt.
11.6 Die Swing-Klassen
11-82
Die Java Foundation Classes
• Die Swing-Bibliothek ersetzt und erweitert die Komponenten- und Behälterklassen
des AWTs.
• Die AWT-Klassen zu Schrift, Farbe und Layout-Manager sowie die Ereignisklassen
werden weiterverwendet.
• Die AWT-Klassen befinden sich im Paket java.awt, die Swingklassen in
javax.swing.
• Die Klassen der Swing-Bibliothek beginnen in der Regel mit dem Buchstaben J.
11.6 Die Swing-Klassen
11-83
AWT und Swing im Vergleich
• Im AWT wird der Peer-Ansatz verfolgt: Alle AWT-Komponenten reichen die
auszuführenden Aktionen an plattformspezifische GUI-Objekte, sogenannte Peers,
weiter. Komponenten, die solche Peer-Objekte benötigen, werden als
schwergewichtig bezeichnet. Diese Komponenten sehen auf unterschiedlichen
Betriebssystemen unterschiedlich aus. Es können nur die Funktionalitäten
bereitgestellt werden, die auf dem jeweiligen Betriebssystem zur Verfügung stehen.
• Fast alle Swing-Komponenten sind vollständig in Java geschrieben und werden
deshalb leichtgewichtig genannt. Form und Funktion sind daher weitgehend
unabhängig vom Betriebssystem. Die Oberfläche kann plattformunabhängig
gestaltet werden und ist noch zur Laufzeit veränderbar (pluggable look and feel).
11.6 Die Swing-Klassen
11-84
Eigenschaften von Swing
• Im Gegensatz zum AWT benutzen Swing-Komponenten nur noch in sehr
eingeschränkter Weise plattformspezifische GUI-Ressourcen.
• Abgesehen von Top-Level-Fenstern, Dialogen und grafischen Primitivoperationen
werden alle GUI-Elemente von Swing selbst erzeugt.
• Ein Swing-Button unter Windows wird nicht mehr vom Windows-UI-Manager
dargestellt, sondern von Swing selbst gezeichnet.
• Diese Vorgehensweise bietet Vorteile. Zwei Beispiele:
◦ Plattformspezifische Besonderheiten fallen weg.
◦ Es entfallen auch Unterschiede in der Bedienung.
11.6 Die Swing-Klassen
11-85
Eigenschaften von Swing
Guido Krüger, Heiko Hansen: Handbuch der Java-Programmierung.
• Eine bemerkenswerte Eigenschaft von Swing ist die Möglichkeit, das Look-and-Feel
(Aussehen und Bedienung einer Anwendung) zur Laufzeit umzuschalten.
• Dieses als Pluggable Look-and-Feel bezeichnete Feature ermöglicht es
beispielsweise einem Windows-Anwender, zwischen unterschiedlichen vordefinierten
Look-and-Feels (zum Beispiel Metal, Motif und Windows) zu wählen.
• Benutzer anderer Betriebssysteme können andere Auswahlmöglichkeiten haben
oder eigene Look-and-Feels zu schreiben.
• Seit Java 7 gibt es ein viertes Standard-Look-and-Feel, das Nimbus-Look-and-Feel.
11.6 Die Swing-Klassen
11-86
Wiederholung: Ein einfaches AWT-Beispiel
import java.awt.*;
public class FrameOhneInhaltAWT {
public static void main(String[] args) {
Frame fenster = new Frame();
fenster.setTitle("Ein AWT-Fenster");
fenster.setLocation(500,400);
fenster.setSize(300,150);
fenster.setVisible(true);
}
}
11.6 Die Swing-Klassen
11-87
Ein einfaches Swing-Beispiel
import javax.swing.*;
public class FrameOhneInhaltSwing {
public static void main(String[] args) {
JFrame fenster = new JFrame();
fenster.setTitle("Ein Swing-Fenster");
fenster.setLocation(500,400);
fenster.setSize(300,150);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
11.6 Die Swing-Klassen
11-88
AWT und Swing im Vergleich
• Es wird aus unterschiedlichen Paketen importiert:
import java.awt.* bzw. import javax.swing.*.
• Die Behälterklassen sind verschieden: Frame bzw. JFrame.
• In der Swing-Variante gibt es eine einfache Möglichkeit zum Schließen eines
Fensters: setDefaultCloseOperation.
• Beim Lauf erzeugt die Swingklasse einen grauen Hintergrund.
11.6 Die Swing-Klassen
11-89
Eine abgeleitete Swing-Klasse
import javax.swing.*;
public class FrameOhneInhalt extends JFrame {
public FrameOhneInhalt () { }
public static void main(String[] args) {
FrameOhneInhalt fenster = new FrameOhneInhalt();
fenster.setTitle("Frame ohne Inhalt");
fenster.setLocation(500,500);
fenster.setSize(300,150);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
11.6 Die Swing-Klassen
11-90
Ein Fenster mit Text
public class FrameMitText extends JFrame {
Container c;
// Container dieses Frames
JLabel beschriftung; // Label, das im Frame erscheinen soll
public FrameMitText() {
c = getContentPane();
c.setLayout(new FlowLayout());
beschriftung = new JLabel("Label-Text im Frame");
c.add(beschriftung);
}
public static void main(String[] args) {
FrameMitText fenster = new FrameMitText();
fenster.setTitle("Frame mit Text im Label"); fenster.setLocation(200,200);
fenster.setSize(300,150); fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}}
11.6 Die Swing-Klassen
11-91
Einordnung der Swingklassen
• Component
◦ Container
∗ Panel
- Applet
· JApplet
∗ Window
- JWindow
- Frame
· JFrame
- Dialog
· JDialog
∗ JComponent
◦ Button, Label, weitere AWT-Komponenten
11.6 Die Swing-Klassen
11-92
Einordnung der Swingklassen
• JComponent
◦ JLabel
◦ AbstractButton
◦ JComboBox
◦ JMenuBar
◦ JList
◦ JScrollBar
◦ JProgressBar
◦ JTextComponent
◦ JPanel
◦ JTable
◦ ...
11.6 Die Swing-Klassen
11-93
Einordnung der Swingklassen
• Die Swing-Behälter-Klassen JFrame, JWindow, . . . sind Erweiterungen der
entsprechenden AWT-Klassen.
• Die Swing-Komponenten-Klassen bilden eine eigene Hierarchie unterhalb von
Container.
• Alle Swing-Klassen stehen unterhalb von Container und erben somit von
Component und Container.
Die gleichzeitige Verwendung von
AWT- und Swing-Komponenten ist zu vermeiden.
11.6 Die Swing-Klassen
11-94
Wiederholung: Die Klasse Component
Die abstrakte Klasse Component steht an oberster Stelle der JFC-Hierachie. Sie stellt
Basismethoden zur Verfügung, die alle AWT- und Swingkomponenten gemeinsam
nutzen können. Die wichtigsten sind:
•
•
•
•
•
•
•
•
Color getBackground(), Color getForeground()
void setBackground(Color c), void setForeground(Color c)
Font getFont, void setFont(Font c)
int getHeight(), int getWidth()
void setSize(int width, int height)
setLocation(int x, int y)
boolean isEnabled(), void setEnabled(boolean b)
boolean isVisible(), void setVisible(boolean b)
11.6 Die Swing-Klassen
11-95
Wiederholung: Die Klasse Container
Behälter sind spezielle Komponenten, die andere Komponenten enthalten können. Die
Klasse Container stellt demzufolge Methoden zum Einfügen, Verwalten und
Entfernen von Komponenten zu Verfügung. Die Komponenten werden in einer Liste
geführt, wobei die Reihenfolge sich durch die Reihenfolge der Einfügungen ergibt oder
durch einen Listenindex bestimmt werden kann. Die Liste wird zur Anordnung der
Komponenten in dem Behälterobjekt benötigt.
•
•
•
•
•
Component add(Component comp)
Component add(Component comp, int index)
Component[] getComponents()
void remove(Component comp)
void setLayout(LayoutManager mgr)
11.6 Die Swing-Klassen
11-96
Die Klasse JComponent
Die abstrakte Klasse JComponent dient als Basisklasse für die Swingkomponenten
mit Ausnahme der Klassen Component und Container. Von diesen beiden Klassen
erbt JComponent und überschreibt dabei einige Methoden. Komponenten können
sowohl durchsichtig (opaque: false) als auch undurchsichtig (opaque: true) sein
und mit einem erläuternden Text, dem sog. Tooltip, versehen werden. Der Text
erscheint, wenn der Mauszeiger einige Sekunden auf der Komponente ruht.
•
•
•
•
boolean isOpaque()
void setOpaque(boolean b)
String getToolTipText()
void setToolTipText(String text)
11.6 Die Swing-Klassen
11-97
Die Klasse JComponent
All Implemented Interfaces:
ImageObserver, MenuContainer, Serializable
Direct Known Subclasses:
AbstractButton, BasicInternalFrameTitlePane, Box, Box.Filler,
JColorChooser, JComboBox, JFileChooser, JInternalFrame,
JInternalFrame.JDesktopIcon, JLabel, JLayeredPane, JList,
JMenuBar, JOptionPane, JPanel, JPopupMenu, JProgressBar,
JRootPane, JScrollBar, JScrollPane, JSeparator, JSlider,
JSpinner, JSplitPane, JTabbedPane, JTable, JTableHeader,
JTextComponent, JToolBar, JToolTip, JTree, JViewport
11.6 Die Swing-Klassen
11-98
Komponenten: Inhalt und Anordnung
Ein Behälterobjekt enthält in der Regel eine oder mehrere Komponenten. Die
Komponenten können Texte, Bilder, Zeichnungen, . . . enthalten. Mithilfe eines
Layoutmanagers werden die Komponenten innerhalb des Behälters angeordnet.
• Mit der Klasse Font (java.awt) können Schriften ausgewählt werden.
• Die Klasse Color (java.awt) stellt Farben zur Verfügung.
• Die abstrakte Klasse Graphics (java.awt) bietet Möglichkeiten zur Erstellung
von Zeichnungen.
• Die Schnittstellen LayoutManager und LayoutManager2 (java.awt) offerieren
Methoden zur Anordnung der Komponenten. Die Schnittstelle Border und die
Klasse BorderFactory (javax.swing) bieten Möglichkeiten zur Gestaltung der
Grenzen zwischen Komponenten.
11.6 Die Swing-Klassen
11-99
Die Klasse FlowLayout
Bei Verwendung der Klasse FlowLayout werden die Komponenten fließend, d. h.
zeilenweise von links nach rechts, angeordnet. Per Default werden die Komponenten
zentriert. Zwischen den Zeilen befindet sich ein Standardabstand von 5 Pixeln, der
aber geändert werden kann. Mit dem Parameter align kann bestimmt werden, ob die
Komponenten links- oder rechtsbündig bzw. zentriert dargestellt werden. hgap und
vgap geben die Abstände zwischen den Komponenten und Zeilen an.
• FlowLayout()
• FlowLayout(int align)
• FlowLayout(int align, int hgap, int vgap)
Der Parameter align kann ein statisches int-Attribut sein:
FlowLayout.LEFT, FlowLayout.RIGHT, FlowLayout.CENTER,
FlowLayout.LEADING, FlowLayout.TRAILING.
11.6 Die Swing-Klassen
11-100
Die Klasse BorderLayout
Bei diesem Layout wird die Behälterfläche in die fünf Bereiche Nord, Ost, Süd, West
und Zentrum aufgeteilt. In jedes dieser Gebiete kann eine Komponente eingefügt
werden. Die Größe von Nord, Ost, Süd und West ergibt sich aus dem jeweiligen
Objekt, während die Größe des Zentrums an die Gesamtgröße des Behälters angepasst
wird. Beispielsweise wird durch add(...,BorderLayout.NORTH) ein Objekt im
oberen und durch add(...,BorderLayout.CENTER) im mittleren Bereich
hinzugefügt.
• BorderLayout()
• BorderLayout(int hgap, int vgap)
11.6 Die Swing-Klassen
11-101
Die Klasse GridLayout
Die Behälterfläche wird gitterartig in z Zeilen und s Spalten aufgeteilt. Die Werte z
und s werden bereits dem Konstruktor übergeben.
• GridLayout()
• GridLayout(int z, int s)
• GridLayout(int z, int s, int hgap, int vgap)
Es gibt etliche weitere Layout-Klassen, z. B. GridBagLayout, BoxLayout,
SpringLayout, OverlayLayout. Im Package java.awt befinden sich die zwei
Schnittstellen LayoutManager und LayoutManager2. Sie enthalten Hinweise auf
Klassen, die diese Schnittstellen implementieren.
11.6 Die Swing-Klassen
11-102
Die Klasse Graphics
• Die abstrakte Klasse Graphics stellt zahlreiche Methoden bereit, die es
ermöglichen, innerhalb des Koordinatensystems einer Komponente zu zeichnen.
Hierzu zählen die Methoden, die wir bereits kennengelernt haben: drawLine,
drawRect, . . . . In einem grafischen Kontext sind die gegenwärtigen Einstellungen
zu Schrift und Farbe sowie die zu bearbeitende Komponente gespeichert.
• Die Klasse Graphics2D ist aus Graphics abgeleitet und erweitert diese um viele
Aspekte, insbesondere um solche zur Darstellung von zweidimensionalen
Zeichnungen.
• Für die Darstellung einer einzelnen Swing-Komponente ist der Repaint-Manager
zuständig. Er sorgt dafür, dass beim erstmaligen Erscheinen und bei Veränderungen
die Methode public void paint(Graphics g) aufgerufen wird.
11.6 Die Swing-Klassen
11-103
Die Komponentenklasse JLabel
Die Klasse JLabel dient zur Darstellung von Texten und Bildern.
public class MyFrame extends JFrame {
Container c;
// Container dieses Frames
JLabel lab;
// Label, das im Frame erscheinen soll
public MyFrame() {
c = getContentPane();
c.setLayout(new FlowLayout());
Icon bild = new ImageIcon("xxx.jpg");
lab = new JLabel("Text", bild, JLabel.CENTER);
lab.setHorizontalTextPosition(JLabel.CENTER);
lab.setVerticalTextPosition(JLabel.BOTTOM);
c.add(lab);
}
...
}
11.6 Die Swing-Klassen
11-104
Die Komponentenklasse AbstractButton
Die abstrakte Klasse bietet verschiedene Arten von Schaltflächen und Knöpfen. Die
wichtigsten Implementierungen sind:
• JButton
• JToggleButton
◦ JCheckBox
◦ JRadioButton
• JMenuItem
(einfache Schaltfläche zum Auslösen von Aktionen)
(Schalter mit zwei Zuständen)
(Kennzeichnung durch Häkchen)
(sich ausschließende Schalter)
(Schaltflächen in einem Menü)
◦ JMenu
◦ JCheckBoxMenuItem
◦ JRadioButtonMenuItem
11.6 Die Swing-Klassen
11-105
Beispiel: JRadioButton
Container c;
JRadioButton rb[] = new JRadioButton[4];
...
public Konstruktor() {
c = getContentPane();
c.setLayout(new FlowLayout());
ButtonGroup bg = new ButtonGroup();
for (int i = 0; i < 4; i++) {
rb[i] = new JRadioButton("Box " + (i+1));
bg.add(rb[i]);
c.add(rb[i]);
}
}
11.6 Die Swing-Klassen
11-106
Die Komponentenklasse JComboBox
• Ein Objekt der Klasse JComboBox ist eine aufklappbare Auswahlliste, die man
mithilfe der Maus oder der Tastatur aufklappen und in der man einen Eintrag
auswählen kann.
• Angezeigt wird dabei jeweils der ausgewählte Eintrag und ein Pfeil nach unten, der
anzeigt, dass es sich um eine aufklappbare Liste handelt.
11.6 Die Swing-Klassen
11-107
Beispiel: JComboBox
Container c;
JComboBox vornamen, nachnamen;
public Konstruktor() {
c = getContentPane();
c.setLayout(new FlowLayout());
String[] namen = {"Hans", "Klaus", "Sabine", "Erika"};
vornamen = new JComboBox(namen);
nachnamen = new JComboBox();
nachnamen.addItem("Meyer"); nachnamen.addItem("Müller");
nachnamen.addItem("Schulze"); nachnamen.addItem("Lehmann");
nachnamen.setSelectedIndex(2);
c.add(vornamen);
c.add(nachnamen);
}
11.6 Die Swing-Klassen
11-108
Die Komponentenklasse JList
• Im Unterschied zur JComboBox-Objekt stellt ein Objekt der Klasse JList eine
Auswahlliste dar, die bereits aufgeklappt ist und daher komplett angezeigt wird.
• In der API steht in der Klasse JList:
A component that displays a list of objects
and allows the user to select one or more items.
• Durch Drücken der Taste Ctrl/Strg können mehrere Einträge ausgewählt
werden. Die ausgewählten Einträge werden markiert. Mit der Shift-Taste kann
ein ganzer Bereich markiert werden.
11.6 Die Swing-Klassen
11-109
Die Komponentenklasse JTextComponent
Die abstrakte Klasse bietet verschiedene Möglichkeiten zur Eingabe von Text. Die
wichtigsten Implementierungen sind:
• JTextArea
• JTextField
◦ JPasswordField
• JTextPane
◦ JHTMLPane
11.6 Die Swing-Klassen
(Eingabe mehrzeiliger Texte)
(Eingabe einzeiliger Texte)
(Eingabe einzeiliger geschützter Texte)
(Eingabe von formatierten Texten)
(z. B. HTML-Texte)
11-110
Die Komponentenklasse JScrollPane
• Objekte der Klasse JScrollPane sind in der Lage, andere Komponenten
aufzunehmen und in einen Darstellungsbereich einzubetten, der mit horizontalen
und vertikalen Bildlaufleisten ausgestattet ist.
• Hierdurch wird eine ausschnittsweise Sicht auf die Komponenten ermöglicht.
• Der jeweilige Ausschnitt wird mit Schiebereglern (scrollbars), die sich am Bildrand
befinden, festgelegt.
11.6 Die Swing-Klassen
11-111
Die Komponentenklasse JPanel
• Objekte der Klasse JPanel können andere Komponenten enthalten. Sie sind daher
eigentlich keine Komponenten, sondern Behälter.
• JPanel ist die Basisklasse für Container, die nicht Hauptfenster sind.
Standardmäßig verwendet JPanel das FlowLayout.
• Objekte der Klasse JPanel werden zum Strukturieren von Behältern
verwendet – und sind aus dieser Sicht Komponenten anderer Behälter.
11.6 Die Swing-Klassen
11-112
Die Behälterklasse JFrame
• Die Klasse JFrame ist die wichtigste Top-Level-Behälterklasse.
• Sie erbt von Frame, ihre Objekte sind daher Fenster mit Rahmen.
• In der Titelleiste des Rahmens befinden sich die üblichen System-Menü-Einträge.
• Zusätzlich zu den Methoden von Frame stellt JFrame weitere zur Verfügung,
z. B. zum Schließen von Fenstern.
11.6 Die Swing-Klassen
11-113
Die Behälterklasse JWindow
• Wie JFrame ist auch JWindow eine Top-Level-Behälterklasse.
• Sie erbt von Window, die Objekte sind daher rahmenlose Fenster.
• Ein JWindow-Objekt kann einem JFrame-Objekt oder einem anderem
JWindow-Objekt gehören. In diesem Fall wird das JWindow-Objekt mit seinem
Besitzer gemeinsam minimiert und maximiert.
• Die Konstruktoren JWindow(Frame owner) und JWindow(Window owner)
erzeugen rahmenlose Fenster, die dem owner gehören. Sie werden zusammen mit
dem owner minimiert und maximiert.
11.6 Die Swing-Klassen
11-114
Die Behälterklasse JDialog
• Die Klasse JDialog wird dazu benutzt, um Dialogfenster darzustellen.
• Dies sind Fenster, die nur solange erscheinen, bis ein Dialog mit dem Benutzer/der
Benutzerin abgewickelt wurde.
• Ein JDialog-Fenster kann einem übergeordneten Fenster gehören. Dieses
übergeordnete kann solange für Benutzereingaben gesperrt werden, bis der Dialog
im Dialogfenster beendet ist.
11.6 Die Swing-Klassen
11-115
Die Klassen JMenuBar und JToolBar
• Einem JFrame-Objekt kann eine Menüleiste hinzugefügt werden. Dies erfolgt mit
Objekten der Klasse JMenuBar.
• Eine Menüleiste verwaltet eine Liste von Menüs vom Typ JMenu.
• Neben Menüleisten sieht man häufig Werkzeugleisten (toolbars). Hierbei handelt es
sich um spezielle Behälter, die meistens Button-Objekte enthalten, die häufig
verwendete Funktionalitäten auslösen können.
• Eine Werkzeugleiste kann als Objekt der Klasse JToolBar erzeugt werden.
11.6 Die Swing-Klassen
11-116
Die Klasse JApplet
• Zur Programmierung von Applets stellt die Swing-Bibliothek die Klasse JApplet
zur Verfügung.
• JApplet ist direkt aus Applet abgeleitet.
• Die Klasse JApplet steht also in der Hierachie unter Component, Container
und Applet und erbt daher die Methoden dieser Klassen.
11.6 Die Swing-Klassen
11-117
Prinzipielle Vorgehensweise
• Durch Instanziieren einer (eigenen) Fensterklasse wird ein Fensterobjekt erzeugt.
Für das Objekt werden Location, Size und Title festgelegt, es wird sichtbar
gemacht, ... Die Klasse geht in der Regel aus der Ableitung einer Behälterklasse
(zum Beispiel JFrame, JWindow, ...) hervor.
• Das Layout und der grafische Kontext werden festgelegt.
• Die Komponenten werden dem Fensterobjekt hinzugefügt (zum Beispiel im
Konstruktor der Fensterklasse).
• Für jede Ereignisquelle werden ein oder mehrere Ereignisempfänger (Beobachter)
sowie die Aktionen zur Ereignisbehandlung definiert. Die Ereignisempfänger werden
bei der zuständigen Ereignisquelle registriert.
11.6 Die Swing-Klassen
11-118
Wiederholung: Adapterklassen
• Eine Adapterklasse implementiert eine Schnittstelle durch leere Rümpfe.
• Zu jeder Low-Level-Listener-Schnittstelle mit mehr als einer Methode existiert eine
Adapterklasse. Ist XxxListener der Name der Schnittstelle, so heißt die
Adapterklasse XxxAdapter. Man schreibt also
class MeinListener extends XxxAdapter
statt
class MeinListener implements XxxListener.
• Beispielsweise enthält die Schnittstelle ActionListener nur eine Methode,
WindowListener jedoch – wie bereits gesehen – mehrere.
11.6 Die Swing-Klassen
11-119
Strukturierung von Behälter- und Beobachterklasse
• Die Beobachterklasse wird als innere Klasse realisiert.
• Die Beobachterklasse wird als anonyme Klasse realisiert.
• Die Fensterklasse wird selbst zur Beobachterklasse.
• Die Beobachterklasse ist eine selbstständige Klasse. Ihr muss der Behälter als
Parameter übergeben werden.
Wir erläutern die Möglichkeiten an einem Beispiel zur Wechsel der Hintergrundfarbe.
Die folgenden Programme wurden D. Ratz, J. Scheffler, D. Seese, J. Wiesenberger:
Grundkurs Programmieren in Java entnommen.
11.6 Die Swing-Klassen
11-120
Realisierung als innere Klasse
public class Farbwechsel1 extends JFrame {
Container c;
JButton button;
public Farbwechsel1() {
c = getContentPane();
button = new JButton("Hintergrundfarbe wechseln");
c.add(button, BorderLayout.NORTH);
ButtonListener bL = new ButtonListener();
button.addActionListener(bL);
}
11.6 Die Swing-Klassen
11-121
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
float zufall = (float) Math.random();
Color grauton = new Color(zufall,zufall,zufall);
c.setBackground(grauton);
}
}
public static void main(String[] args) {
Farbwechsel1 fenster = new Farbwechsel1();
fenster.setTitle("Farbwechsel");
fenster.setLocation(200,200);
fenster.setSize(500,500);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
11.6 Die Swing-Klassen
11-122
Realisierung als anonyme Klasse
public class Farbwechsel2 extends JFrame {
Container c;
JButton button;
public Farbwechsel2() {
c = getContentPane();
button = new JButton("Hintergrundfarbe wechseln");
c.add(button, BorderLayout.NORTH);
ActionListener bL = new ActionListener() {
public void actionPerformed(ActionEvent e) { ... }
};
button.addActionListener(bL);
}
public static void main(String[] args) { ... }
}
11.6 Die Swing-Klassen
11-123
Fensterklasse als Beobachterklasse
public class Farbwechsel3 extends JFrame implements ActionListener {
Container c;
JButton button;
public Farbwechsel3() {
c = getContentPane();
button = new JButton("Hintergrundfarbe wechseln");
c.add(button, BorderLayout.NORTH);
button.addActionListener(this);
}
public void actionPerformed(ActionEvent e) { ... }
public static void main(String[] args) { ... }
}
11.6 Die Swing-Klassen
11-124
Beobachterklasse als selbstständige Klasse
public class Farbwechsel4 extends JFrame {
Container c;
JButton button;
public Farbwechsel4() {
c = getContentPane();
button = new JButton("Hintergrundfarbe wechseln");
c.add(button, BorderLayout.NORTH);
ButtonListener bL = new ButtonListener(c);
button.addActionListener(bL);
}
public static void main(String[] args) { ... }
}
11.6 Die Swing-Klassen
11-125
Beobachterklasse als selbstständige Klasse
public class ButtonListener implements ActionListener {
Container c;
public ButtonListener(Container c) {
this.c = c;
}
public void actionPerformed(ActionEvent e) {
float zufall = (float) Math.random();
Color grauton = new Color(zufall,zufall,zufall);
c.setBackground(grauton);
}
}
11.6 Die Swing-Klassen
11-126
Beispiel: Fenster mit Menü- und Werkzeugleiste
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Bilderrahmen extends JFrame {
Container c;
JMenuBar menuBar;
JMenu menu;
JMenuItem menuItem;
JToolBar toolBar;
JButton button;
JLabel bildLabel;
11.6 Die Swing-Klassen
//
//
//
//
//
//
//
Container dieses Frames
Menueleiste
Menue
Menue-Eintrag
Werkzeugleiste
Knoepfe der Werkzeugleiste
Label das im Frame erscheinen soll
11-127
public Bilderrahmen() {
c = getContentPane();
MenuListener mL = new MenuListener();
menuBar = new JMenuBar();
menu = new JMenu("Bilder");
menu.setMnemonic(KeyEvent.VK_B); // kombiniert mit Alt_Taste
// API sagt: KeyEvent indicates keystroke in a component
// Wörterbuch sagt: keystroke = Tastendruck oder Tastenanschlag
menuItem = new JMenuItem("Hund");
menuItem.setMnemonic(KeyEvent.VK_H);
menuItem.addActionListener(mL);
menuItem.setActionCommand("dog");
menu.add(menuItem);
11.6 Die Swing-Klassen
11-128
menuItem = new JMenuItem("Katze");
menuItem.setMnemonic(KeyEvent.VK_K);
menuItem.addActionListener(mL);
menuItem.setActionCommand("cat");
menu.add(menuItem);
menuItem = new JMenuItem("Maus");
menuItem.setMnemonic(KeyEvent.VK_M);
menuItem.addActionListener(mL);
menuItem.setActionCommand("mouse");
menu.add(menuItem);
11.6 Die Swing-Klassen
11-129
menuBar.add(menu);
setJMenuBar(menuBar);
ToolBarListener tL = new ToolBarListener();
toolBar = new JToolBar("Rahmenfarbe");
button = new JButton(new ImageIcon("images/rot.gif"));
button.setToolTipText("roter Rahmen");
button.addActionListener(tL);
button.setActionCommand("rot");
toolBar.add(button);
11.6 Die Swing-Klassen
11-130
button = new JButton(new ImageIcon("images/gruen.gif"));
button.setToolTipText("gruener Rahmen");
button.addActionListener(tL);
button.setActionCommand("gruen");
toolBar.add(button);
button = new JButton(new ImageIcon("images/blau.gif"));
button.setToolTipText("blauer Rahmen");
button.addActionListener(tL);
button.setActionCommand("blau");
toolBar.add(button);
bildLabel = new JLabel(new ImageIcon("images/dog.gif"));
11.6 Die Swing-Klassen
11-131
c.setBackground(Color.red);
c.add(bildLabel, BorderLayout.CENTER);
c.add(toolBar, BorderLayout.NORTH);
}
class MenuListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
bildLabel.setIcon(new ImageIcon("images/"+e.getActionCommand()+".gif"));
}
}
11.6 Die Swing-Klassen
11-132
class ToolBarListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "rot")
c.setBackground(Color.red);
else if (e.getActionCommand() == "gruen")
c.setBackground(Color.green);
else if (e.getActionCommand() == "blau")
c.setBackground(Color.blue);
}
}
11.6 Die Swing-Klassen
11-133
public static void main(String[] args) {
Bilderrahmen fenster = new Bilderrahmen();
fenster.setTitle("Bilderrahmen");
fenster.setLocation(200,200);
fenster.setSize(180,280);
fenster.setVisible(true);
fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
11.6 Die Swing-Klassen
11-134
Swing-Klassen
Als Beispiele für Swing-Klassen haben wir u. a. die Klassen/Schnittstellen
JFrame, JWindow, JApplet, JComponent,
JButton, JCheckBox, JComboBox, JDialog,
JLabel, JList, JMenu, JMenuBar, JMenuItem,
JPanel, JPassword, JRadioButton, JScrollBar,
JTable, JTextArea, JTextComponent, JTextField,
JToggleButton, JToolBar, ...
kennengelernt. Es gibt etliche weitere Swing-Klassen/Schnittstellen:
JFileChooser, JColorChooser, JInternalFrame,
JSeparator, JSlider, JSpinner, JSplitPane, ...
Als weiteres Beispiel sehen wir uns die Klasse JFileChooser an.
11.6 Die Swing-Klassen
11-135
Die Komponentenklasse JFileChooser
Eine relativ häufige Aufgabe ist die Auswahl eines Dateinamens zum Öffnen oder
Speichern einer Datei. Die Klasse JFileChooser aus dem Paket javax.swing
bietet ein Dialogfenster an, mit dem man im Dateisystem navigieren und die
gewünschte Datei auswählen kann.
In der API steht:
JFileChooser provides a simple mechanism for the user to choose a file.
public class JFileChooser extends JComponent implements ...
11.6 Die Swing-Klassen
11-136
Die Komponentenklasse JFileChooser
Konstruktoren:
JFileChooser()
JFileChooser(String ordner)
JFileChooser(File ordner)
Start: Home-Ordner
Start: ordner
Start: ordner
Einige Methoden:
int showOpenDialog(Component c)
int showSaveDialog(Component c)
Öffnet einen Dialog mit einem Button zum Öffnen bzw. Speichern.
Der Dialog erscheint zentriert über der Komponente c.
Rückgabe ist eine Konstante für den Button:
APPROVE_OPTION Öffnen/Speichern
CANCEL_OPTION
Abbruch
ERROR_OPTION
Fehler oder das Fenster wurde vom Anwender geschlossen.
11.6 Die Swing-Klassen
11-137
Die Komponentenklasse JFileChooser
Weitere Methoden (nicht alle):
int showDialog(Component c, String text)
Öffnet einen Dialog mit einem Button mit der Beschriftung text.
Der Dialog erscheint über der Komponente c.
void setSelectedFile(File datei)
Setzt die ausgewählte Datei als Vorgabewert auf datei.
File getSelectedFile()
Liefert die vom Anwender ausgewählte Datei.
void setFileFilter(FileFilter filter)
Setzt den Dateifilter auf filter.
11.6 Die Swing-Klassen
11-138
Die Komponentenklasse JFileChooser
Ein Beispiel für die Verwendung von JFileChooser:
// Start: aktueller Ordner
JFileChooser dateiAuswahl = new JFileChooser(".");
int status = dateiAuswahl.showOpenDialog(this);
if (status == JFileChooser.APPROVE_OPTION) {
File datei = dateiAuswahl.getSelectedFile();
.....
}
JFileChooser dient hier zur Ermittlung des Dateinamens. Das Laden oder
Speichern muss noch programmiert werden.
11.6 Die Swing-Klassen
11-139
Die Komponentenklasse JFileChooser
In der API steht das folgende Beispiel zum Einsatz eines Filters für die Datei:
The following code pops up a file chooser for the user’s home
directory that sees only .jpg and .gif images:
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
chooser.setFileFilter(filter);
int returnVal = chooser.showOpenDialog(parent);
if(returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " +
chooser.getSelectedFile().getName());
}
11.6 Die Swing-Klassen
11-140
Herunterladen