Tag 9: Grafische Benutzeroberflächen

Ähnliche Dokumente
1. Konventionelle Ein-/Ausgabebetonte Programmierung

Universität Paderborn Prof. Dr. Stefan Böttcher. Abschluss von Kapitel 2: Programmierung Grafischer Oberflächen mit der Swing-Bibliothek

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 15/16. Kapitel 7. Grafische Benutzeroberflächen 1

Kurs: Programmieren in Java

Einführung in die Programmierung für NF. Grafische Benutzeroberflächen

Einstieg in die Informatik mit Java

Benutzeroberflächen. Abstract Windowing Toolkit, Rahmen, Wächter, Ereignisbehandlung, Ausgabe, Menüs.

B1. Ein-/Ausgabebetonte Programmierung

Objektorientierte Software-Entwicklung

Institut für Programmierung und Reaktive Systeme. GUIs mit Swing. Markus Reschke

(C) Sortieren und Suchen mit Java.-AWT Seite 1

EAD II Übung 5. Graphische Benutzungsoberfläche mit BlueJ

GUI Programmierung mit JAVA Swing

Java - AWT Basispraktikum SystemArchitektur WS 2008/ Atanas Dimitrov

Grafikprogrammierung mit Java Teil 1/2

Aufgabe 1: Objekte, Klassen, Vererbung (15 Punkte)

Kapitel 8: Grafische Benutzerschnittstellen

Graphische Benutzungsoberflächen

Grundlagen der Programmierung (GP) Prof. Dr. H. Schlingloff Joachim Hänsel

Ziele. Kapitel 8: Grafische Benutzerschnittstellen. AWT und Swing. Ziele (2)

Ereignisverwaltung und Layout-Typen

Einführung in die Programmierung für NF. Übung

B1. Ein-/Ausgabebetonte Programmierung

Seite Architektur interaktiver Systeme. 7. Architektur interaktiver Systeme. 7.1 Entkopplung durch Sichten. Schichtenarchitektur

Programmieren II. Java im Vergleich zu anderen Sprachen. Einführung: GUI. Einführung: Grafische Benutzeroberflächen. Dr.

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 11/12. Kapitel 7. Grafische Benutzeroberflächen

Zentrale Objekte zur Programmierung graphischer Benutzeroberflächen (GUI)

B1. Ein-/Ausgabebetonte Programmierung

Programmieren 2 Selbststudium Semesterwoche 4

Ist eine Softwarekomponente, die dem Benutzer eines Computers die Interaktion mit der Maschine über grafische Symbole erlaubt

Eventhandling. Delegation model Eventhandler model

Beispiel: Eine Choice-Liste...

Vorlesung Informatik II

Probeklausur Informatik 2 Sommersemester 2013

Heute. Grafische Benutzeroberflächen (Anonyme) innere Klassen Einfache Simulationen main / ausführbare jar-files IT I - VO 11 1

Objektorientierte Programmierung

Ereignisse (Events) in Java

7. Architektur interaktiver Systeme

Was passiert, wenn Button "Ok?" mit Maus angeklickt?

GUI-Programmierung. Teil I. Unterlagen zum Modul OOP mit Java V by MOU2/BFH-TI. Berner Fachhochschule Technik und Informatik

Übung Nr. 20 Freitag, 09:00-11:00 Uhr in E3.301

Einstieg in die Informatik mit Java

Einführung in GUI-Programmierung. javax.swing

Neben der Verwendung von Klassen ist Vererbung ein wichtiges Merkmal objektorientierter

Speichern der Benutzereinstellungen

Einführung in die OOP mit Java

Javakurs für Fortgeschrittene

Probeklausur: Programmierung WS04/05

Eventhandling. Delegation model Eventhandler model

Einführung: Grafische Benutzeroberflächen. Programmieren II. Dr. Klaus Höppner. Hochschule Darmstadt Sommersemester / 22

I. Grundlagen II. Ereignistypen III. Ereignisempfänger. Event-Handling (EH)

Objektorientierte Programmierung OOP Objektorientierte Programmierung (OOP) mit Java

Programmierung Nachklausurtutorium

Fakultät Angewandte Informatik Programmierung verteilter Systeme Übungen zur Vorlesung Informatik II, Blatt 8

Graphical User Interfaces

7. Architektur interaktiver Systeme

Images. Kommen auf zweierlei Weise zur Anwendung. Darstellung von Pixelbildern(.jpg,.gif,.png) Bilden die Grundlage für Offscreendrawing

GUI-Programmierung mit Java. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 11: GUI 1: AWT (1) GUI-Programmierung mit Java.

Objektorientierte Programmierung Studiengang Medieninformatik

Grafische Benutzeroberflächen

GUI Programmierung in Java

Softwaretechnik (Medieninformatik): GUIs mit Swing Überblick

Universität Paderborn Prof. Dr. Stefan Böttcher. Kapitel 3: Java Applets

import java.awt.*; import java.awt.event.*; import javax.swing.*;

AK-Automatisierungs und Kommunikationstechnik TI Technische Informatik. NWT Netzwerktechnik

Einführung in GUI-Programmierung. javax.swing

GRAFISCHE BENUTZERSCHNITTSTELLEN

Grafikausgabe mit dem Abstract- Windowing-Toolkit. Eine Einführung

Eingabe von Texten. Vorlesung Software-Entwicklung / Folie 101

Lösungsvorschläge zur Nachklausur zum Kurs 1618 Sommersemester 2001 am

Funktionale und Objekt-Orientierte Programmierkonzepte

Schablonen für Klassen, Interfaces oder Methoden, die noch nicht festgelegte Datentypen verwenden

Graphische Benutzungsoberflächen mit Java. Einführung in NetBeans

Programmieren II. Events (Ereignisse) Heusch 16.6 (2. Bd) Ratz 15. Institut für Angewandte Informatik

Programmieren II. Events (Ereignisse) Heusch 16.6 (2. Bd) Ratz 15. Institut für Angewandte Informatik

CS1005 Objektorientierte Programmierung Bachelor of Science (Informatik)

Grafische Benutzeroberflächen

Benutzeroberflächen. Java Teil 4

11. GUI-Programmierung mit SWING Überblick

/** Main-Methode erzeugt einen neuen Editor zum Testen */ public static void main(string[] args) { new Editor();

Wiederholung. Klassenhierarchie:

Praktikum 4: Grafiken und Ereignisse

Proinformatik: Objektorientierte Programmierung - Tag 6 -

Konzepte objektorientierter Programmierung

Java I Vorlesung 11 Graphische Oberflächen mit Swing

NTB Druckdatum:

Instrumentierung und Dekodierung

Ein erstes "Hello world!" Programm

Grafische Benutzeroberflächen

Auswahl aus mehreren Alternativen:

Drucken. Programmieren II. Martin Schultheiß. Hochschule Darmstadt Sommersemester 2011

Begriffe 1 (Wiederholung)

$ java awt.main A # typische Dekodierung $ java -Dtrace=all awt.main A # alle Events $ java -Dtrace=none awt.main A # keine Dekodierung

Transkript:

Kapitel 10 Tag 9: Grafische Benutzeroberflächen In Java gibt es zunächst zwei verschiedene Möglichkeiten Klassen für die Grafikausgabe zu verwenden. Eine Möglichkeit ist AWT (=Abstrakt Windows Toolkit) und die andere ist Swing. Die Erzeugung von Fenstern ist in beiden Varianten zunächst sehr ähnlich, aber spätenstens beim Füllen der Fensterflächen unterschieden sich beide sehr. Wir werden in den folgenden Abschnitten AWT näher besprechen. 10.1 Fenstermanagment unter AWT 10.1.1 Ein Fenster erzeugen Wir können schon mit wenigen Zeilen ein Fenster erzeugen, indem wir die Klasse Frame im package java.awt verwenden. 1 import j a v a. awt. Frame ; 2 p u b l i c c l a s s M e i n E r s t e s F e n s t e r { 3 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 4 / / ö f f n e t e i n AWT F e n s t e r 5 Frame f = new Frame ("So einfach geht das?" ) ; 6 f. s e t S i z e ( 3 0 0, 2 0 0 ) ; 7 f. s e t V i s i b l e ( true ) ; 8 9 / / L e i d e r l ä s s t es s i c h noch n i c h t s c h l i e s s e n : ), a b e r STRG+C 10 / / b e e n d e t d i e Anwendung und s c h l i e s s t das F e n s t e r... 11 } 12 } Unser Programm liefert folgende Ausgabe: Nach der Erzeugung des Fensters ist die Ausgabeposition die linke obere Ecke des Bildschirms. 105

106 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 10.1.2 Das Fenster zentrieren Um das Fenster nun zu zentrieren, lesen wir zunächst die Bildschirmgrösse ein und setzen dann die Koordinaten des Fensters entsprechend. 2 p u b l i c c l a s s F e n s t e r P o s i t i o n i e r e n extends Frame { 3 p u b l i c F e n s t e r P o s i t i o n i e r e n ( i n t x, i n t y ) { 4 s e t T i t l e ("Ab in die Mitte!" ) ; 5 s e t S i z e ( x, y ) ; 6 Dimension d = T o o l k i t. g e t D e f a u l t T o o l k i t ( ). g e t S c r e e n S i z e ( ) ; 7 s e t L o c a t i o n ( ( d. width g e t S i z e ( ). width ) / 2, 8 ( d. h e i g h t g e t S i z e ( ). h e i g h t ) / 2 ) ; 9 s e t V i s i b l e ( true ) ; 10 } 11 12 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 13 F e n s t e r P o s i t i o n i e r e n f = new F e n s t e r P o s i t i o n i e r e n ( 2 0 0, 1 0 0 ) ; 14 } 15 } Nun wird das Fenster in der Mitte positioniert. 10.1.3 Zeichenfunktionen innerhalb des Fensters verwenden AWT bietet eine Reihe von Zeichenfunktionen an. Alle mit ihren Feinheiten zu beschreiben würde wieder ein ganzes Buch füllen. Wir wollen an dieser Stelle nur ein paar grundlegende Beispiele erläutern und den Leser motivieren, spätestens hier die Java API [29] als Hilfsmittel zu verwenden. 10.1.3.1 Textausgaben Wir wollen mit dem einfachen Beispiel beginnen, einen Text innerhalb des Fensterbereichs auszugeben. Zusätzlich zeigen wir in diesem Beispiel, wie sich die Farben des Vorder- und Hintergrunds verändern lassen.

10.1. FENSTERMANAGMENT UNTER AWT 107 2 p u b l i c c l a s s T e x t F e n s t e r extends Frame { 3 p u b l i c T e x t F e n s t e r ( S t r i n g t i t e l ) { 4 s e t T i t l e ( t i t e l ) ; 5 s e t S i z e ( 5 0 0, 3 0 0 ) ; 6 s e t B a c k g r o u n d ( Color. l i g h t G r a y ) ; 7 s e t F o r e g r o u n d ( Color. r e d ) ; 8 s e t V i s i b l e ( true ) ; 9 } 10 11 p u b l i c void p a i n t ( G r a p h i c s g ) { 12 g. d r a w S t r i n g ("Was soll ich nur schreiben?", 120, 60 ) ; 13 } 14 15 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 16 T e x t F e n s t e r t = new T e x t F e n s t e r ("Text im Fenster" ) ; 17 } 18 } 10.1.3.2 Zeichenelemente Exemplarisch zeigt dieses Beispiel die Verwendung der Zeichenfunktionen: drawrect und drawline. Auch hier haben wir eine zusätzliche Funktionalität eingebaut, die Wartefunktion. 2 p u b l i c c l a s s T e x t F e n s t e r 2 extends Frame { 3 p u b l i c T e x t F e n s t e r 2 ( S t r i n g t i t e l ) { 4 s e t T i t l e ( t i t e l ) ; 5 s e t S i z e ( 5 0 0, 3 0 0 ) ; 6 s e t B a c k g r o u n d ( Color. l i g h t G r a y ) ; 7 s e t F o r e g r o u n d ( Color. r e d ) ; 8 s e t V i s i b l e ( true ) ; 9 } 10 11 p u b l i c s t a t i c void wartemal ( long m i l l i s ) { 12 t r y { 13 Thread. s l e e p ( m i l l i s ) ; 14 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { } 15 } 16 17 p u b l i c void p a i n t ( G r a p h i c s g ) { 18 g. drawrect ( 3 0, 5 0, 4 4 0, 2 0 0 ) ; 19 g. s e t C o l o r ( Color. b l a c k ) ; 20 g. drawline ( 3 0, 1 5 0, 4 7 0, 1 5 0 ) ; 21 g. s e t F o n t ( new Font ("SansSerif", Font.BOLD, 2 0 ) ) ;

108 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 22 g. d r a w S t r i n g ("Schick!", 60, 8 0 ) ; 23 wartemal ( 3 0 0 0 ) ; 24 g. d r a w S t r i n g ("Geht so...", 350, 2 2 0 ) ; 25 } 26 27 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 28 T e x t F e n s t e r 2 t = new T e x t F e n s t e r 2 ("Text im Fenster" ) ; 29 } 30 } Unser Programmcode liefert nach der Ausführung folgende Ausgabe...... und ca. 3 Sekunden später...... eine weitere verzögerte zusätzliche Ausgabe. 10.1.3.3 Die Klasse Color verwenden Für grafische Benutzeroberflächen sind Farben sehr wichtig. Um das RGB-Farbmodell zu verwenden, erzeugen wir viele farbige Rechtecke, deren 3 Farbkomponenten rot, grün und blau zufällig gesetzt werden. Dazu erzeugen wir ein Color-Objekt und setzen diese Farbwerte. 2 import j a v a. u t i l. Random ; 3 4 p u b l i c c l a s s T e x t F e n s t e r 3 extends Frame { 5 p u b l i c T e x t F e n s t e r 3 ( S t r i n g t i t e l ) { 6 s e t T i t l e ( t i t e l ) ; 7 s e t S i z e ( 5 0 0, 3 0 0 ) ;

10.1. FENSTERMANAGMENT UNTER AWT 109 8 s e t B a c k g r o u n d ( Color. l i g h t G r a y ) ; 9 s e t F o r e g r o u n d ( Color. r e d ) ; 10 s e t V i s i b l e ( true ) ; 11 } 12 13 p u b l i c s t a t i c void wartemal ( long m i l l i s ) { 14 t r y { 15 Thread. s l e e p ( m i l l i s ) ; 16 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { } 17 } 18 19 p u b l i c void p a i n t ( G r a p h i c s g ) { 20 Random r = new Random ( ) ; 21 g. c l e a r R e c t ( 0, 0, getwidth () 1, g e t H e i g h t ( ) 1 ) ; 22 23 f o r ( i n t y =30; y< g e t H e i g h t () 10; y += 15) 24 f o r ( i n t x =12; x< getwidth () 10; x += 15) { 25 g. s e t C o l o r ( new Color ( r. n e x t I n t ( 2 5 6 ), 26 r. n e x t I n t ( 2 5 6 ), 27 r. n e x t I n t ( 2 5 6 ) ) ) ; 28 g. f i l l R e c t ( x, y, 10, 10 ) ; 29 g. s e t C o l o r ( Color.BLACK ) ; 30 g. drawrect ( x 1, y 1, 10, 1 0 ) ; 31 } 32 } 33 34 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 35 T e x t F e n s t e r 3 t = new T e x t F e n s t e r 3 ("Farbe im Fenster" ) ; 36 } 37 } 10.1.3.4 Bilder laden und anzeigen Mit der Methode drawimage können wir Bilder anzeigen lassen. In den Zeilen 20 und 21 geschieht aber leider nicht das, was wir erwarten würden. Die Funktion getimage bereitet das Laden des Bildes nur vor. Der eigentliche Ladevorgang erfolgt erst beim Aufruf von drawimage. Das hat zum einen den Nachteil, dass bei einer Wiederverwendung der Methode paint jedesmal das Bild neu geladen wird. 2 import j a v a. u t i l. Random ; 3 4 p u b l i c c l a s s T e x t F e n s t e r 4 extends Frame { 5 p u b l i c T e x t F e n s t e r 4 ( S t r i n g t i t e l ) { 6 s e t T i t l e ( t i t e l ) ; 7 s e t S i z e ( 5 0 0, 3 0 0 ) ;

110 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 8 s e t B a c k g r o u n d ( Color. l i g h t G r a y ) ; 9 s e t F o r e g r o u n d ( Color. r e d ) ; 10 s e t V i s i b l e ( true ) ; 11 } 12 13 p u b l i c s t a t i c void wartemal ( long m i l l i s ) { 14 t r y { 15 Thread. s l e e p ( m i l l i s ) ; 16 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { } 17 } 18 19 p u b l i c void p a i n t ( G r a p h i c s g ) { 20 Image p i c = T o o l k i t. g e t D e f a u l t T o o l k i t ( ). getimage ("C:\\maja.jpg" ) ; 21 g. drawimage ( pic, 20, 20, t h i s ) ; 22 } 23 24 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 25 T e x t F e n s t e r 4 t = new T e x t F e n s t e r 4 ("Text im Fenster" ) ; 26 } 27 } Wir können aber mit Hilfe der Klasse Mediatracker die Bilder vor der eigentlichen Anzeige in den Speicher laden. Dazu verwenden wir folgende Zeilen beispielsweise im Konstruktor: 1 Image img ; 2... 3 img = g e t T o o l k i t ( ). getimage ("c:\\maja.jpg" ) ; 4 M e d i a t r a c k e r mt = new M e d i a t r a c k e r ( t h i s ) ; 5 mt. addimage ( img, 0 ) ; 6 t r y { 7 mt. w a i t F o r A l l ( ) ; 8 } catch ( I n t e r r u p t e d E x c e p t i o n e ) { } 9... 10 g. drawimage ( img, 20, 20, t h i s ) ; 10.1.4 Fenster- und Mausereignisse behandeln Als Standardfensterklasse werden wir in den folgenden Abschnitten immer von dieser erben: 1 / K l a s s e : M e i n F e n s t e r 2 S t a n d a r d f e n s t e r, d a s s z e n t r i e r t e r z e u g t ( a b e r 3 noch n i c h t a n g e z e i g t ) wird. 4 /

10.1. FENSTERMANAGMENT UNTER AWT 111 5 import j a v a. awt. ; 6 7 p u b l i c c l a s s M e i n F e n s t e r extends Frame { 8 p u b l i c M e i n F e n s t e r ( S t r i n g t i t e l, i n t w, i n t h ) { 9 t h i s. s e t T i t l e ( t i t e l ) ; 10 t h i s. s e t S i z e (w, h ) ; 11 12 / / z e n t r i e r e das F e n s t e r 13 Dimension d = T o o l k i t. g e t D e f a u l t T o o l k i t ( ). g e t S c r e e n S i z e ( ) ; 14 t h i s. s e t L o c a t i o n ( ( d. width t h i s. g e t S i z e ( ). width ) / 2, 15 ( d. h e i g h t t h i s. g e t S i z e ( ). h e i g h t ) / 2 ) ; 16 } 17 } Die Klasse MeinFenster erzeugt ein auf dem Bildschirm zentriertes Fenster und kann mit einem Konstruktor und den Attributen titel, breite und hoehe erzeugt werden. 10.1.4.1 Fenster schliessen mit dem Interface WindowListener Unser folgendes Beispiel erbt zunächst von der Klasse MeinFenster und implementiert anschliessend das Interface WindowListener. In Zeile 10 fügen verknüpfen wir unsere Anwendung mit dem WindowListener und erreichen damit, dass bei Ereignissen, wie Fenster schliessen oder Fenster aktivieren Methoden aufgerufen werden, die wir implementiert haben. 1 / K l a s s e : F e n s t e r S c h l i e s s t 2 A b g e l e i t e t von M e i n F e n s t e r 3 i m p l e m e n t i e r t WindowListener 4 s c h l i e s s t F e n s t e r a u t o m a t i s c h 5 / 6 import j a v a. awt. ; 7 import j a v a. awt. e v e n t. ; 8 p u b l i c c l a s s F e n s t e r S c h l i e s s t extends M e i n F e n s t e r 9 implements WindowListener { 10 p u b l i c F e n s t e r S c h l i e s s t ( S t r i n g t i t e l, i n t w, i n t h ) { 11 super ( t i t e l, w, h ) ; 12 addwindowlistener ( t h i s ) ; / / wir r e g i s t r i e r e n h i e r den E r e i g n i s t y p 13 / / f ü r WindowEvents 14 s e t V i s i b l e ( true ) ; 15 } 16 17 / / 18 / / Hier werden d i e WindowListener Methoden i m p l e m e n t i e r t 19 / / Methode : F e n s t e r wird g e s c h l o s s e n 20 p u b l i c void windowclosing ( WindowEvent e v e n t ) { 21 System. e x i t ( 0 ) ; 22 } 23 p u b l i c void windowclosed ( WindowEvent e v e n t ) {} 24 p u b l i c void windowdeiconified ( WindowEvent e v e n t ) {} 25 p u b l i c void w i n d o w I c o n i f i e d ( WindowEvent e v e n t ) {} 26 p u b l i c void windowactivated ( WindowEvent e v e n t ) {} 27 p u b l i c void windowdeactivated ( WindowEvent e v e n t ) {} 28 p u b l i c void windowopened ( WindowEvent e v e n t ) {} 29 / / 30 31 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 32 F e n s t e r S c h l i e s s t f = new F e n s t e r S c h l i e s s t ("Schliesse mich!", 200, 1 0 0 ) ; 33 } 34 }

112 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN In Zeile 18 verwenden wir die Funktion System.exit(0). Es werden alle Fenster der Anwendung geschlossen und das Programm beendet. Leider haben wir mit der Implementierung des Interfaces WindowListener den Nachteil, dass wir alle Methoden implementieren müssen. Das Programm wird schnell unüberschaubar, wenn wir verschiedene Eventtypen abfangen wollen und für jedes Interface alle Methoden implementieren müssen. Hilfe verspricht die Klasse WindowAdapter, die das Interface WindowListener bereits mit leeren Funktionskörpern implementiert hat. Wir können einfach von dieser Klasse erben und eine der Methoden überschreiben. Um die restlichen brauchen wir uns nicht zu kümmern. 1 / K l a s s e : F e n s t e r S c h l i e s s t S c h i c k 2 A b g e l e i t e t von M e i n F e n s t e r 3 i m p l e m e n t i e r t WindowListener 4 s c h l i e s s t F e n s t e r a u t o m a t i s c h 5 / 6 import j a v a. awt. ; 7 import j a v a. awt. e v e n t. ; 8 p u b l i c c l a s s F e n s t e r S c h l i e s s t S c h i c k extends M e i n F e n s t e r { 9 p u b l i c F e n s t e r S c h l i e s s t S c h i c k ( S t r i n g t i t e l, i n t w, i n t h ) { 10 super ( t i t e l, w, h ) ; 11 / / Wir verwenden e i n e Klasse, d i e nur d i e gewünschten Methoden 12 / / d e r K l a s s e WindowAdapter ü b e r s c h r e i b t. 13 addwindowlistener ( new WindowClosingAdapter ( ) ) ; 14 s e t V i s i b l e ( true ) ; 15 } 16 17 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 18 F e n s t e r S c h l i e s s t S c h i c k f = 19 new F e n s t e r S c h l i e s s t S c h i c k ("Schliesse mich!", 200, 1 0 0 ) ; 20 } 21 } 22 23 / Etwas n e r v i g war es, a l l e Methoden, d i e das I n t e r f a c e WindowListener 24 a n g e b o t e n hat, ü b e r s c h r e i b e n zu müssen. Angenehmer i s t es, d i e 25 WindowAdapter K l a s s e zu verwenden. S i e h a t a l l e F u n k t i o n e n b e r e i t s 26 mit l eerem Programmkörper i m p l m e n t i e r t. Wollen wir nur e i n e F u n k t i o n 27 verwenden, so können wir i n e i n e r S u b k l a s s e von WindowAdapter d i e 28 gewünschte Methode ü b e r s c h r e i b e n. In diesem F a l l, windowclosing. 29 / 30 c l a s s WindowClosingAdapter extends WindowAdapter { 31 p u b l i c void windowclosing ( WindowEvent e ) { 32 System. e x i t ( 0 ) ; 33 } 34 } Wie können auch die Klasse WindowClosingAdapter als innere Klasse deklarieren. 2 import j a v a. awt. e v e n t. ; 3 4 p u b l i c c l a s s F e n s t e r S c h l i e s s t S c h i c k 2 extends M e i n F e n s t e r { 5 p u b l i c F e n s t e r S c h l i e s s t S c h i c k 2 ( S t r i n g t i t e l, i n t w, i n t h ) { 6 super ( t i t e l, w, h ) ; 7 addwindowlistener ( new WindowClosingAdapter ( ) ) ; 8 s e t V i s i b l e ( true ) ; 9 } 10 11 / / 12 / / i n n e r e K l a s s e 13 p r i v a t e c l a s s WindowClosingAdapter extends WindowAdapter { 14 p u b l i c void windowclosing ( WindowEvent e ) { 15 System. e x i t ( 0 ) ;

10.1. FENSTERMANAGMENT UNTER AWT 113 16 } 17 } 18 / / 19 20 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 21 F e n s t e r S c h l i e s s t S c h i c k 2 f = 22 new F e n s t e r S c h l i e s s t S c h i c k 2 ("Schliesse mich!", 200, 1 0 0 ) ; 23 } 24 } Eine noch kürzere Schreibweise könnten wir erreichen, indem wir die Klasse WindowAdapter nur lokal erzeugen und die Funktion überschreiben (wie wir es bei dem sehr übersichtlich gestalteten Galileo-Onlinebuch [15] von Christian Ullenboom erfahren können). Wir nennen solche Klassen innere, anonyme Klassen. 1 import j a v a. awt. e v e n t. ; 2 p u b l i c c l a s s F e n s t e r S c h l i e s s t S c h i c k K u r z extends M e i n F e n s t e r { 3 p u b l i c F e n s t e r S c h l i e s s t S c h i c k K u r z ( S t r i n g t i t e l, i n t w, i n t h ) { 4 super ( t i t e l, w, h ) ; 5 / / Wir verwenden e i n e i n n e r e anonyme K l a s s e. Kurz und knapp. 6 addwindowlistener ( new WindowAdapter ( ) { 7 p u b l i c void windowclosing ( WindowEvent e ) { 8 System. e x i t ( 0 ) ; 9 } 10 } ) ; 11 s e t V i s i b l e ( true ) ; 12 } 13 14 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 15 F e n s t e r S c h l i e s s t S c h i c k K u r z f = 16 new F e n s t e r S c h l i e s s t S c h i c k K u r z ("Schliesse mich!", 200, 1 0 0 ) ; 17 } 18 } Dieses Verfahren werden wir ab sofort für kleine Funktionen verwenden. Sollten die Funktionen zu gross werden, greifen wir auf die privaten Klassen zurück. 10.1.4.2 GUI-Elemente und ihre Ereignisse Wir werden uns nun exemplarisch Beispiele anschauen, bei denen GUI-Elemente erzeugt und auf Aktionen reagiert werden. Die Komponente Button 2 import j a v a. awt. e v e n t. ; 3 p u b l i c c l a s s GUI_Button extends M e i n F e n s t e r { 4 B u tton b u t t o n 1, b u t t o n 2 ; 5 Label l a b e l 1 ; 6 7 / / Im K o n s t r u k t o r e r z e u g e n wir d i e GUI Elemente 8 p u b l i c GUI_Button ( S t r i n g t i t e l, i n t w, i n t h ) { 9 super ( t i t e l, w, h ) ; 10 s e t S i z e (w, h ) ; 11 12 / / Wir r e g i s t r i e r e n den WindowListener, um a u f 13 / / WindowEvents r e a g i e r e n zu können 14 addwindowlistener ( new MeinWindowListener ( ) ) ;

114 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 15 16 / / wir bauen e i n e n A c t i o n L i s t e n e r, d e r nur a u f Knopfdruck 17 / / r e a g i e r t 18 A c t i o n L i s t e n e r a k t i o n = new Knopfdruck ( ) ; 19 20 s e t L a y o u t ( new FlowLayout ( ) ) ; 21 b u t t o n 1 = new B u tton ("Linker Knopf" ) ; 22 add ( b u t t o n 1 ) ; 23 b u t t o n 1. a d d A c t i o n L i s t e n e r ( a k t i o n ) ; 24 b u t t o n 1. setactioncommand ("b1" ) ; 25 b u t t o n 2 = new B u tton ("Rechter Knopf" ) ; 26 add ( b u t t o n 2 ) ; 27 b u t t o n 2. a d d A c t i o n L i s t e n e r ( a k t i o n ) ; 28 b u t t o n 2. setactioncommand ("b2" ) ; 29 l a b e l 1 = new Label ("Ein Label" ) ; 30 add ( l a b e l 1 ) ; 31 s e t V i s i b l e ( true ) ; 32 } 33 34 / / 35 / / I n n e r e K l a s s e n f ü r das Eventmanagment 36 c l a s s MeinWindowListener extends WindowAdapter { 37 p u b l i c void windowclosing ( WindowEvent e v e n t ) { 38 System. e x i t ( 0 ) ; 39 } 40 } 41 42 c l a s s Knopfdruck implements A c t i o n L i s t e n e r { 43 p u b l i c void a c t i o n P e r f o r m e d ( A c t i o n E v e n t e ) { 44 l a b e l 1. s e t T e x t ( e. getactioncommand ( ) ) ; 45 } 46 } 47 / / 48 49 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 50 GUI_Button f = new GUI_Button ("Schliesse mich!", 500, 5 0 0 ) ; 51 } 52 }

10.1. FENSTERMANAGMENT UNTER AWT 115 Auf die Ereignisse individuell reagieren, Anzeige aber mit anderem LayoutManager: 2 import j a v a. awt. e v e n t. ; 3 4 p u b l i c c l a s s GUI_Button_Aktion extends M e i n F e n s t e r { 5 B u tton b u t t o n 1, b u t t o n 2 ; 6 Label l a b e l 1 ; 7 8 / / Im K o n s t r u k t o r e r z e u g e n wir d i e GUI Elemente 9 p u b l i c GUI_Button_Aktion ( S t r i n g t i t e l, i n t w, i n t h ) { 10 super ( t i t e l, w, h ) ; 11 s e t S i z e (w, h ) ; 12 13 / / Wir r e g i s t r i e r e n den WindowListener, um a u f 14 / / WindowEvents r e a g i e r e n zu können 15 addwindowlistener ( new MeinWindowListener ( ) ) ; 16 17 / / wir bauen e i n e n A c t i o n L i s t e n e r, d e r nur a u f Knopfdruck 18 / / r e a g i e r t 19 A c t i o n L i s t e n e r a k t i o n = new Knopfdruck ( ) ; 20 21 s e t L a y o u t ( new BorderLayout ( ) ) ; 22 23 b u t t o n 1 = new B u tton ("Linker Knopf" ) ; 24 add ( b u t t o n 1, BorderLayout.NORTH) ; 25 b u t t o n 1. a d d A c t i o n L i s t e n e r ( a k t i o n ) ; 26 b u t t o n 1. setactioncommand ("b1" ) ; 27 28 b u t t o n 2 = new B u tton ("Rechter Knopf" ) ; 29 add ( b u t t o n 2, BorderLayout.SOUTH ) ; 30 b u t t o n 2. a d d A c t i o n L i s t e n e r ( a k t i o n ) ; 31 b u t t o n 2. setactioncommand ("b2" ) ; 32 33 l a b e l 1 = new Label ("Platz für ein Label" ) ; 34 add ( l a b e l 1, BorderLayout. CENTER ) ; 35 36 s e t V i s i b l e ( true ) ; 37 } 38 39 p r i v a t e void B u t t o n 1 C l i c k e d ( ) { 40 l a b e l 1. s e t T e x t ("Button1" ) ; 41 } 42 43 p r i v a t e void B u t t o n 2 C l i c k e d ( ) { 44 l a b e l 1. s e t T e x t ("Button2" ) ; 45 } 46 / / 47 / / I n n e r e K l a s s e n f ü r das Eventmanagment 48 c l a s s MeinWindowListener extends WindowAdapter { 49 p u b l i c void windowclosing ( WindowEvent e v e n t ) { 50 System. e x i t ( 0 ) ; 51 } 52 } 53 54 c l a s s Knopfdruck implements A c t i o n L i s t e n e r { 55 p u b l i c void a c t i o n P e r f o r m e d ( A c t i o n E v e n t e ) { 56 / / wir b e h a n d e l n d i e E r e i g n i s s e 57 S t r i n g cmd = e. getactioncommand ( ) ; 58 i f ( cmd. e q u a l s ("b1" ) ) 59 B u t t o n 1 C l i c k e d ( ) ; 60 i f ( cmd. e q u a l s ("b2" ) ) 61 B u t t o n 2 C l i c k e d ( ) ;

116 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 62 } 63 } 64 / / 65 66 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 67 GUI_Button_Aktion f = new GUI_Button_Aktion ("Klick mich...", 500, 5 0 0 ) ; 68 } 69 } Die Komponente TextField 2 import j a v a. awt. e v e n t. ; 3 4 p u b l i c c l a s s GUI_Button_TextField extends M e i n F e n s t e r { 5 B u tton b u t t o n 1 ; 6 Label l a b e l 1 ; 7 T e x t F i e l d t e x t f i e l d 1 ; 8 9 / / Im K o n s t r u k t o r e r z e u g e n wir d i e GUI Elemente 10 p u b l i c GUI_Button_TextField ( S t r i n g t i t e l, i n t w, i n t h ) { 11 super ( t i t e l, w, h ) ; 12 s e t S i z e (w, h ) ; 13 14 / / Wir r e g i s t r i e r e n den WindowListener, um a u f 15 / / WindowEvents r e a g i e r e n zu können 16 addwindowlistener ( new MeinWindowListener ( ) ) ; 17 18 / / wir bauen e i n e n A c t i o n L i s t e n e r, d e r nur a u f Knopfdruck 19 / / r e a g i e r t 20 A c t i o n L i s t e n e r a k t i o n = new Knopfdruck ( ) ; 21 22 s e t L a y o u t ( new FlowLayout ( ) ) ; 23 24 t e x t f i e l d 1 = new T e x t F i e l d ("hier steht schon was", 2 5 ) ; 25 add ( t e x t f i e l d 1 ) ; 26

10.1. FENSTERMANAGMENT UNTER AWT 117 27 b u t t o n 1 = new B u tton ("Knopf" ) ; 28 add ( b u t t o n 1 ) ; 29 b u t t o n 1. a d d A c t i o n L i s t e n e r ( a k t i o n ) ; 30 b u t t o n 1. setactioncommand ("b1" ) ; 31 32 l a b e l 1 = new Label ("noch steht hier nicht viel" ) ; 33 add ( l a b e l 1 ) ; 34 35 s e t V i s i b l e ( true ) ; 36 } 37 38 p r i v a t e void B u t t o n 1 C l i c k e d ( ) { 39 S t r i n g t x t = t e x t f i e l d 1. g e t T e x t ( ) ; 40 l a b e l 1. s e t T e x t ( t x t ) ; 41 } 42 43 / / 44 / / I n n e r e K l a s s e n f ü r das Eventmanagment 45 c l a s s MeinWindowListener extends WindowAdapter { 46 p u b l i c void windowclosing ( WindowEvent e v e n t ) { 47 System. e x i t ( 0 ) ; 48 } 49 } 50 51 c l a s s Knopfdruck implements A c t i o n L i s t e n e r { 52 p u b l i c void a c t i o n P e r f o r m e d ( A c t i o n E v e n t e ) { 53 / / wir b e h a n d e l n d i e E r e i g n i s s e 54 S t r i n g cmd = e. getactioncommand ( ) ; 55 i f ( cmd. e q u a l s ("b1" ) ) 56 B u t t o n 1 C l i c k e d ( ) ; 57 } 58 } 59 / / 60 61 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 62 GUI_Button_TextField f = 63 new GUI_Button_TextField ("Klick mich...", 500, 5 0 0 ) ; 64 } 65 }

118 KAPITEL 10. TAG 9: GRAFISCHE BENUTZEROBERFLÄCHEN 10.1.4.3 Auf Mausereignisse reagieren 2 import j a v a. awt. e v e n t. ; 3 p u b l i c c l a s s MausKlick extends M e i n F e n s t e r { 4 p u b l i c MausKlick ( S t r i n g t i t e l, i n t w, i n t h ) { 5 super ( t i t e l, w, h ) ; 6 / / Wir verwenden e i n e i n n e r e anonyme K l a s s e. Kurz und knapp. 7 addwindowlistener ( new WindowAdapter ( ) { 8 p u b l i c void windowclosing ( WindowEvent e ) { 9 System. e x i t ( 0 ) ; 10 } 11 } ) ; 12 a d d M o u s e L i s t e n e r ( new MouseAdapter ( ) { 13 p u b l i c void mousepressed ( MouseEvent e ) { 14 G r a p h i c s g = g e t G r a p h i c s ( ) ; 15 g. s e t C o l o r ( Color. g r e e n ) ; 16 g. f i l l O v a l ( 5 0, 5 0, 1 0, 1 0 ) ; 17 } 18 } ) ; 19 } 20 21 p u b l i c s t a t i c void main ( S t r i n g [ ] a r g s ) { 22 MausKlick f = new MausKlick ("Schliesse mich!", 200, 1 0 0 ) ; 23 } 24 } Liefert nach Klick mit der Maus, innhalb des Fensters, folgende Ausgabe: 10.2 Das Projekt Taschenrechner Mit den Erkenntnissen, die wir aus den vorhergehenden Kapiteln gewonnen haben, wollen wir nun eine erste richtige Anwendung mit AWT schreiben. Unser Ziel ist es einen Taschenrechner zu implementieren, der auf verschiedene Eingaben reagiert und Operationen auf diesen Eingaben ausführen kann.