• Keine Ergebnisse gefunden

Grafikprogrammierung in Java: Grundlagen

N/A
N/A
Protected

Academic year: 2022

Aktie "Grafikprogrammierung in Java: Grundlagen"

Copied!
134
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Grafikprogrammierung in Java:

Grundlagen

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(2)

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.

• 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

◦ . . .

(3)

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.

(4)

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.

(5)

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-, Tastatur- und Fensterereignissen

• Dialogelemente zur Kommunikation mit dem Anwender

• Fortgeschrittene Operationen zur Ausgabe von Bitmaps und Tönen

(6)

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();

}

(7)

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,

(8)

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

(9)

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();

} }

(10)

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)

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

(12)

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.

(13)

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);

(14)

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:

(15)

Die Klasse WindowAdapter

void windowActivated(WindowEvent e) void windowClosed(WindowEvent e) void windowClosing(WindowEvent e)

void windowDeactivated(WindowEvent e) void windowDeiconified(WindowEvent e) void windowGainedFocus(WindowEvent e) void windowIconified(WindowEvent e) void windowLostFocus(WindowEvent e) void windowOpened(WindowEvent e)

void windowStateChanged(WindowEvent e)

(16)

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!");

} }

(17)

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);

} }

(18)

public class EinfachesFenster extends Frame { EinfachesFenster(String title) {

super(title);

addWindowListener(new WindowClosingAdapter());

setBackground(Color.yellow);

setSize(400,200);

add(new Rechteck());

setVisible(true);

} }

(19)

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);

(20)

Grafikprogrammierung in Java:

Grafische Grundelemente

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(21)

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.

(22)

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.

(23)

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.

(24)

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).

(25)

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.

(26)

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.

(27)

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.

(28)

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( ... )

(29)

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.

(30)

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.

(31)

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

(32)

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 Wert Bedeutung Font.PLAIN 0 Standard-Font

Font.BOLD 1 Fettdruck

Font.ITALIC 2 Kursivdruck

3 fetter Kursivdruck

(33)

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);

(34)

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));

} }

(35)

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)

(36)

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 Rot Grün Blau

Weiß 255 255 255

Grau 127 127 127

Schwarz 0 0 0

Rot 255 0 0

Grün 0 255 0

Blau 0 0 255

Gelb 255 255 0

Magenta 255 0 255

Cyan 0 255 255

Java unterstützt weitere Farbmodelle, in denen Farben z. B. durch Farbton, Intensität und Helligkeit dargestellt werden.

(37)

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.

(38)

Erzeugung von Farben

• Die Klasse Color stellt etliche Farben als statische Objekte zur Verfügung:

◦ static Color black

◦ static Color red

◦ static Color green

◦ static Color blue

◦ . . .

• Von einem bestehenden Farbobjekt kann der RGB-Wert mit den Methoden

◦ int getRed(),

◦ int getGreen() und

◦ int getBlue() ermittelt werden.

(39)

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.

(40)

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);

...

}

(41)

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

(42)

Grafikprogrammierung in Java:

Fensterklassen

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(43)

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

◦ Button

◦ Canvas

◦ Checkbox

◦ Choice

◦ Label

◦ List

◦ Scrollbar

◦ Textcomponent

(44)

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, . . .

(45)

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

(46)

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 aufzurufen.

(47)

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.

(48)

Grafikprogrammierung in Java:

Ereignisse und Widgets

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(49)

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.

(50)

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.

(51)

Ereignisklassen

• EventObject

◦ AWTEvent

∗ ComponentEvent - FocusEvent - InputEvent - KeyEvent - MouseEvent - ContainerEvent - WindowEvent

∗ ActionEvent

∗ AdjustmentEvent

∗ ItemEvent

∗ TextEvent

(52)

EventListener-Schnittstellen

• EventListener

◦ FocusListener

◦ ActionListener

◦ AdjustmentListener

◦ ItemListener

◦ TextListener

◦ KeyListener

◦ MouseListener

◦ MouseMotionListener

◦ WindowListener

◦ ContainerListener

◦ ComponentListener

(53)

Low-Level-Events

Beispiel: Window-Events

• windowOpened

• windowActivated, windowDeactivated

• windowClosed

• windowClosing

• windowIconified, windowDeiconified

(54)

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)

(55)

Widgets

• Textfelder und Textbereiche

• Auswahlboxen

• Listen

• Canvas

• Panels

• Dateidialogboxen (nicht für Applets)

• Menüs (nicht für Applets)

(56)

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.

(57)

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;

(58)

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);

}

(59)

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);

}

(60)

public void adjustmentValueChanged(AdjustmentEvent e) { schieberWert = schieber.getValue();

repaint();

}

(61)

public static void main(String[] args) { WindowBlind f = new WindowBlind();

f.setSize(400,300);

f.setVisible(true);

} }

(62)

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);

}

(63)

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();

} }

(64)

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.

(65)

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)

(66)

Grafikprogrammierung in Java:

Applets

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(67)

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.

(68)

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);

} }

(69)

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>

(70)

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.

(71)

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.

(72)

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.

(73)

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

(74)

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;

(75)

public void init () {

setBackground(Color.white);

schieber = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,101);

add(schieber);

schieber.addAdjustmentListener(this);

}

(76)

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);

}

(77)

public void adjustmentValueChanged(AdjustmentEvent e) { schieberWert = schieber.getValue();

repaint();

} }

(78)

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

(79)

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

(80)

Grafikprogrammierung in Java:

Die Swing-Klassen

11.1 Grundlagen

11.2 Grafische Grundelemente 11.3 Fensterklassen

11.4 Ereignisse und Widgets 11.5 Applets

11.6 Die Swing-Klassen

(81)

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.

(82)

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

(83)

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.

(84)

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).

(85)

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.

(86)

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.

(87)

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);

}

(88)

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);

} }

(89)

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.

(90)

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);

}

(91)

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);

(92)

Einordnung der Swingklassen

• Component

◦ Container

∗ Panel - Applet

· JApplet

∗ Window - JWindow - Frame

· JFrame - Dialog

· JDialog

∗ JComponent

◦ Button, Label, weitere AWT-Komponenten

(93)

Einordnung der Swingklassen

• JComponent

◦ JLabel

◦ AbstractButton

◦ JComboBox

◦ JMenuBar

◦ JList

◦ JScrollbar

◦ JProgressbar

◦ JTextComponent

◦ JPanel

◦ JTable

◦ ...

(94)

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.

(95)

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)

(96)

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)

(97)

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)

(98)

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

(99)

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.

(100)

Die Klasse FlowLayout

Bei Verwendung der Klasse FlowLayout werden die Komponenten fließend, d. h.

zeilenweise von links nach rechts, angeordnet. Innerhalb einer Zeile 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. hp und vp bestimmen die Abstände zwischen den Komponenten und Zeilen.

• FlowLayout()

• FlowLayout(int align)

• FlowLayout(int align, int hp, int vp)

(101)

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 hp, int vp)

(102)

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 hp, int vp)

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.

(103)

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.

(104)

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);

} ...

(105)

Die Komponentenklasse AbstractButton

Die abstrakte Klasse bietet verschiedene Arten von Schaltflächen und Knöpfen. Die wichtigsten Implementierungen sind:

• JButton (einfache Schaltfläche zum Auslösen von Aktionen)

• JToggleButton (Schalter mit zwei Zuständen)

◦ JCheckBox (Kennzeichnung durch Häkchen)

◦ JRadioButton (sich ausschließende Schalter)

• JMenuItem (Schaltflächen in einem Menü)

◦ JMenu

◦ JCheckBoxMenuItem

◦ JRadioButtonMenuItem

(106)

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]);

} }

(107)

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.

(108)

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);

}

(109)

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.

(110)

Die Komponentenklasse JTextComponent

Die abstrakte Klasse bietet verschiedene Möglichkeiten zur Eingabe von Text. Die wichtigsten Implementierungen sind:

• JTextArea (Eingabe mehrzeiliger Texte)

• JTextField (Eingabe einzeiliger Texte)

◦ JPasswordField (Eingabe einzeiliger geschützter Texte)

• JTextPane (Eingabe von formatierten Texten)

◦ JHTMLPane (z. B. HTML-Texte)

(111)

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.

(112)

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.

(113)

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.

(114)

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.

(115)

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.

(116)

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.

(117)

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.

(118)

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.

(119)

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.

(120)

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.

(121)

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);

}

(122)

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.setSize(200,100);

fenster.setVisible(true);

fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

} }

(123)

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) { ... } }

(124)

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) { ... }

}

(125)

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) { ... } }

(126)

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);

} }

(127)

Beispiel: Fenster mit Menü- und Werkzeugleiste

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class Bilderrahmen extends JFrame {

Container c; // Container dieses Frames JMenuBar menuBar; // Menueleiste

JMenu menu; // Menue

JMenuItem menuItem; // Menue-Eintrag JToolBar toolBar; // Werkzeugleiste

JButton button; // Knoepfe der Werkzeugleiste

JLabel bildLabel; // Label das im Frame erscheinen soll

(128)

public Bilderrahmen() { c = getContentPane();

MenuListener mL = new MenuListener();

menuBar = new JMenuBar();

menu = new JMenu("Bilder");

menu.setMnemonic(KeyEvent.VK_B); // kombiniert mit Alt_Taste menuItem = new JMenuItem("Hund");

menuItem.setMnemonic(KeyEvent.VK_H);

menuItem.addActionListener(mL);

menuItem.setActionCommand("dog");

menu.add(menuItem);

Referenzen

ÄHNLICHE DOKUMENTE

Ein Interface kann aufgefasst werden als eine abstrakte Klasse, wobei:.. • alle Objekt-Methoden

There are eight steps to installing the HP-IB configuration programs onto your system. The programs are in a file called hpibcnfg. tar .Z, which is in tbe usr/contrib/bin

It also supplies state information to the remote node to allow management of the link (Layer 2 Protocol). Data and state information IS packaged in units known as

If the line attachment is not enabled, all commands (except Control No-op, Enable and Dial) are rejected with unit check set in the CSW and the command reject bit set in sense

synonymous with multipoint line. An all binary-O character that occupies a posi- tion in the storage buffer and is displayed as a blank position. In reading the contents of the

O adaptador de corrente alterna converte a voltagem da corrente alterna de uma tomada eléctrica em voltagem de corrente contínua para abastecer a PhotoPC 850Z. Para saber

Schreiben Sie die Funktion inorder mit akkumulierendem Parameter für binäre

Wenn in einer &#34;Klasse&#34; KEINE Methode implementiert ist, wird sie als interface &#34;Schnittstelle&#34; bezeichnet. public interface