Ereignisse, AWT GUI Elemente

Werbung
Ereignisse, MVC, AWT
Ereignisse
■ Merkmale eines ereignisgesteuerten Programms
That's
That'sone
onesmall
smallstep
step
for
foraaman,
man,aagiant
giantleap
leap
for
mankind
for mankind
■ Aufbau eines ereignisgesteuerten Programms
■ Entwicklung eines ereignisgesteuertes Programms in Java
■ Allgemeines zur Benutzerschnittstelle, MVC
■ Unterteilung in Model, View und Controller
■ Graphische Komponenten des AWT
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Sequentielle Programme
Beispiele sequentieller Programme
■ Hauptprogramm steuert den gesamten Programmablauf: in Java schreibt man
dafür sog. Applikationen: die main Methode ist dort die Einsprungstelle (später)
■ Compiler, Batch-Processing, Scripts, Kommandozeilenbefehle (cd, dir,
more),
2 von 62
public class App {
static foo() {... }
■ Applets ohne graphische Benützeroberfläche (Methode paint ist dort
Einsprungstelle)
public static void main(String args) {
foo();
}
}
■ Programmablauf wird beim Programmieren festgelegt
■ Hauptprogramm ruft Unterprogramm(e) auf.
■
Diese geben am Ende jeweils die Kontrolle wieder an das
Hauptprogramm zurück.
Æ weniger geeignet für wirklich interaktive Programme
■ Verlangt an bestimmten Stellen Benutzereingaben
■ Zeitlicher Ablauf des Programms ist vor dem Start festgelegt
■ User kann nur an den vorbestimmten Stellen auf den Programmablauf Einfluss
nehmen, nämlich dort, wo das Programm eine Eingabe verlangt
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
3 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
4 von 62
Ereignisgesteuertes Programm
Ereignisgesteuerte Programme
■ Interaktive Anwendungen werden in Java mit ereignisgesteuerten Programmen
(event-driven programs) geschrieben
■ Hauptmerkmal: Programmablauf ist nicht
fix vorgegeben, sondern wird durch
externe Ereignisse (events) gesteuert:
■
■
■
■ Für die Benutzerschnittstelle wird von Java eine graphische Oberfläche zur
Verfügung gestellt
Æ GUI Graphical User Interface (AWT, JFC)
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
■
Ereignis(endlos)schleife Methoden
im UserProgramm
Mausklick
Menuauswahl
Tastendruck
Betriebssystem, andere Programme
Ereignisschleife (event loop)
■ Das Hauptprogramm besteht aus einer
Ereignisschleife
■ Diese wartet auf Ereignisse und läuft bis
zum Abbruch des Programms
kontinuierlich
■ Der Programmierer schreibt für jedes
Ereignis eine entsprechende Methode
■ Beim Eintreffen eines Ereignisses ruft
die Ereignisschleife die entsprechende
Methode auf, um das eingetroffene
Ereignis zu behandeln
5 von 62
School of Engineering
Java Event Model
■ Java Laufzeitsystem (AWT) implementiert eine Ereignisschleife bereits
Ereignisquelle (Source Object), z.B. Button
■ Der Programmierer muss nur noch die Methoden schreiben, die die Ereignisse
behandeln
■ Definiert Ereignisse, die es erzeugen kann
■
Benutzer drückt auf Taste oder klickt mit der Maus
Benutzer klickt eine Schaltfläche, eine Menuoption usw. an
■ Die Java GUI Komponenten (z.B. Button) bereiten diese Elementarereignisse
auf
■
■ Sie erzeugen daraus Java Ereignisse
■
© A. Meier/M. Braschler/J. Zeman/K. Rege
Methode2
Methode2
Maustaste
Maustaste
betätigt?
betätigt?
Methode3
Methode3
….?
….?
Methode4
Methode4
….?
….?
:
:
6 von 62
7 von 62
bietet Methoden zum An- und Abmelden von
Listener an. z.B. addActionListener
■ Informiert Listener-Objekte, sobald
ein Ereignis eingetreten ist:
■ Sie nehmen Elementarereignisse, die sie betreffen, entgegen
School of Engineering
Maus
Maus
bewegt?
bewegt?
■ Führt eine Liste der Ereignissenken
(Listener-Objekte), z.B. Applet
■ Die Ereignisschleife verarbeitet zusammen mit dem Betriebssystem die
Elementarereignisse des Systems
■
Methode1
Methode1
© A. Meier/M. Braschler/J. Zeman/K. Rege
Ereignisschleife und Events in Java
■
Taste
Taste
gedrückt?
gedrückt?
Das Source-Objekt ruft die entsprechende
Methode beim Listener-Objekt auf
Alle Informationen über das Ereignis (z.B. wer ist der Verursacher)
werden dabei in einem Ereignis-Objekt übergeben
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
8 von 62
…Java Event Model
Beispiel
Interface
Interface->->Klasse
Klasseenthält
enthält
Methode
MethodeaddActionListener
addActionListener
Listener, z.B. Applet
import java.applet.*;
■ Registriert sich beim Source-Objekt
als Listener
public class DrueckMich extends Applet implements ActionListener {
private Button tester;
private boolean gedrueckt = false;
@Override
public void init() {
tester = new Button("Hier drücken"); // GUI-Obj. erzeugen
add (tester);
// zur GUI hinzufügen
tester.addActionListener(this);
// Listener registrieren
}
Sich selber anmelden an Knopf,
Bearbeitungsmethode
Sich selber anmelden an Knopf,
Bearbeitungsmethode
dass an ActionEvents interessiert
dass an ActionEvents interessiert
public void actionPerformed(ActionEvent event) {
gedrueckt = true;
repaint();
}
Ereignis
Ereignis
■ Gibt damit an, an welchen Ereignissen es
interessiert ist (Bsp. ActionEvent).
■ Stellt je eine Methode zur Behandlung
der entsprechenden Ereignisse bereit
■ Interface bestimmt die Behandlungsmethode,
z.B.ActionListener
SourceObj.addActionListener(ListenerObj)
Delegation-Event-Modell
■ Auftretende Ereignisse werden nicht
zentral behandelt
@Override
public void paint(Graphics g) {
if(gedrueckt) {
g.drawString ("Danke!", 100,50);
}
}
■ Behandlung jedes Ereignisses wird
vielmehr an ein oder mehrere Objekte delegiert
School of Engineering
import java.awt.*;
import java.awt.event.*;
© A. Meier/M. Braschler/J. Zeman/K. Rege
}
9 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
10 von 62
Initialisierung
Anmeldung: z.B. addActionListener
Methode init()
■ Vordefinierte Methode der Klasse Applet
Æ Wird ein einziges Mal bei der Initialisierung des Applet aufgerufen
■ In dieser Methode werden normalerweise alle benötigten Komponenten erzeugt
und initialisiert
■ Allgemein sieht die Erzeugung eines Buttons folgendermassen aus:
tester = new Button("Hier drücken");
■ Dem Button tester wird ein Objekt als Listener für ActionEvents zugeordnet.
Methode add()
■ Vordefinierte Methode der Klasse Applet
© A. Meier/M. Braschler/J. Zeman/K. Rege
■
■
Mit this wird hier das aktuelles Objekt (Applet) beim Button tester als Listener registriert;
Æ d.h. die Methode für die Ereignisbehandlung (actionPerformed) befindet sich in diesem
Applet !!
Man hätte aber auch andere Objekte im Programm mit der Ereignissbehandlung "beauftragen"
können.
■ Die Registrierungsmethoden für Listener-Objekte folgen einer einheitlichen
Namensgebung. Ein Listener für ein Ereignis XXX hat den Namen
■ Fügt den Button zur graphischen Benutzeroberfläche hinzu
■ Man könnte hier auch schreiben add(tester);
School of Engineering
tester.addActionListener(this);
SourceObjekt.addXXXListener(Listener-Obj.);
11 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
12 von 62
Bearbeitung bei Ereignis: z.B. actionPerformed
Ereignisklassen: z.B. ActionEvent
■ Die Methode actionPerformed(ActionEvent e) wird vom Button tester
■ Es gibt zahlreiche Ereignisse, welche von Komponenten erzeugt werden können
und an denen andere Objekte interessiert sind
(Komponente = GUI-Objekte)
jedesmal bei allen registrierten Listeners aufgerufen, wenn der Button gedrückt
wird
■ In dieser Methode stehen die Anweisungen, die dieses Ereignis behandeln
■ Dieselbe Ereignisklasse wird von mehreren Komponenten verwendet.
Z.B. ActionEvent
■ Wenn die Betätigung des Buttons eine Veränderung der GUI zur Folge hat (im
Bsp.: drawString…), dann muss das Applet muss neu gezeichnet werden, um
dem Benutzer die Reaktion des Programms anzuzeigen:
Æ verwendet von Button, TextField,...
repaint() fordert den Browser auf, das Applet neu zu zeichnen
■ Der Browser ruft sodann unter anderem die Methode paint() des Applets auf
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
13 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Mehrere Buttons ActionEvent Object
… Mehrere Buttons ActionEvent Object
Mehrere Buttons
… Mehrere Buttons
public void init {
smaller= new Button("smaller"); //
add (smaller);
//
smaller.addActionListener(this);//
bigger= new Button("bigger");
//
add (bigger);
//
bigger.addActionListener(this); //
}
14 von 62
■ Mit der Methode e.getSource() kann das Source-Objekt abgefragt werden
GUI-Obj. erzeugen
zur GUI addieren
Listener registrieren
GUI-Obj. erzeugen
zur GUI addieren
Listener registrieren
■ Problem: Alle Buttons erzeugen ein Ereignis der gleichen Klasse ActionEvent
und es wird die gleiche Methode ActionPerfomed aufgerufen .
■ Wie kann man herausfinden, welcher Button das Ereignis erzeugt hat?
public void actionPerformed(ActionEvent event) {
if (event.getSource() == smaller){
diameter -= 10;
Referenzvergleich
Referenzvergleich
}
if (event.getSource() == larger){
diameter += 10;
}
repaint();
}
■ Lösung: Das an die Methode actionPerformed(ActionEvent e)
übergebene Ereignis-Objekt e enthält verschiedene Informationen zum Ereignis:
z.B. Quelle des Ereignisses
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
15 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
16 von 62
Direkte Verarbeitung von Events in Applet
■ Bearbeitung des Ereignisses in Applet:
■
■
Einfach
ausreichend für einfache Aufgaben
addXXListner(this)
addXXListner(this)
Entwurf von interaktiven Anwendungen
Model, View, Controller
■ Nachteile:
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
17 von 62
■
Verarbeitung ans Applet gebunden
-> bei Wechsel auf andere GUI Klassenbibliothek neu programmieren
■
Vermischung von Darstellungslogik und Verarbeitungslogik
-> Übersichtlichkeit leidet
■
Nicht möglich gleiches Ereignis durch mehrere GUI Elemente auszulösen
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
18 von 62
MVC: Beispiel Auto
Trennung GUI und Verarbeitung
■ Wichtiges Entwurfsprinzip: Trennung und Entkopplung von Benutzerschnittstelle
und „technischen Innereien“ (Verarbeitung, Modell)
Controller
Controller
■ Beispiel: Automobil
■
■
View
View
Benutzerschnittstelle: Gaspedal, Kupplungspedal, Ganghebel,
Steuerrad, Tachometer, Tourenzähler, Benzinanzeige...
Technische Innereien: Motor, Getriebe, Kupplung,
Lenkung, ABS, Lichtanlage
■ Vorteile:
■
■
■
Einfache und sichere Bedienung und Überwachung durch User
Verstecken der Komplexität vor dem User
Getrennte und damit einfachere Entwicklung und Wartung der Teilsysteme
Model
Model
■ Man unterscheidet 3 Teile: Model, View und Controller
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
19 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
20 von 62
Aufgabenteilung nach dem MVC Paradigma
Vereinfachte Implementierung
■ Bearbeitung/Daten von Darstellung und Auslösen der Verarbeitung trennen
■ Controller und View sind meist miteinander gekoppelt bzw. in einer Klasse
implementiert
■
■
verschiedene Eingaben (Buttons, etc.)
verschiedene Darstellungen (gleichzeitig)
■
■
Controller delegiert Verarbeitung nur
wird deshalb meist nicht als separaten Klasse implementiert
■ Klare Aufgabenteilung (Separation of Concerns)
BenutzerereignisVerarbeitung
Darstellung
Controller
Controller
1) initiiert
Änderung
der Daten
View
1) initiiert
Änderung
der Daten
2) benachrichtigt über
Datenänderung
Viewer
2) benachrichtigt
über Datenänderung
3) liest neue Daten und
stellt diese dar
Model
3) liest neue Daten und
stellt diese dar
Model
Datenbehälter, inkl.
Veränderungsmethoden
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
21 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Beispiel
Einfache View
■ Ein veränderbarer Kreis mit Methoden grow und shrink
import java.awt.*; import java.awt.event.*;
import java.applet.*;import java.beans.*;
■ View-Controller als Applet implementiert
public class Applet1 extends Applet
implements ActionListener, PropertyChangeListener
{
CircleModel model;
Button grow;
View-Controller
Modelle
Modellehaben
haben
oft
oftProperties
Properties
==Werte
Werte
public void init()
{
grow = new Button("Grow");
grow.addActionListener(this);
add(grow);
model = new CircleModel(50);
model.addPropertyChangeListener(this);
}
public void actionPerformed(ActionEvent ev) {
model.grow();
}
CircleModel
int value
grow()
shrink()
22 von 62
public void paint(Graphics g) {
int r = model.getValue();
g.drawOval(100-r,100-r,2*r,2*r);
}
Model
Controller
View
public void propertyChange(PropertyChangeEvent ev) {
repaint();
}
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
23 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
24 von 62
1) Initiieren der Datenänderung
Controller
1) initiiert
Änderung
der Daten
2) Benachrichtigung über Datenänderungen
Controller
Viewer
2) benachrichtigt
über Datenänderung
Viewer
1) initiiert
Änderung
der Daten
3) liest neue Daten und
stellt diese dar
2) benachrichtigt
über Datenänderung
3) liest neue Daten und
stellt diese dar
Model
Model
Ereignismechanismus verwenden:
PropertyChangedEvent
■ der Controller ruft die entsprechende Methode vom Model auf
■ 2a) View meldet sich beim Model an, dass an Ereignissen interessiert:
public void actionPerformed(ActionEvent ev)
{
model.grow(); // nur noch Methodenaufruf
}
■ addPropertyChangeListener(this)
■
einmalig, bei der Initialisierung
■ 2b) Ereignisbearbeiter-Methode
■ propertyChange
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
25 von 62
3) Lesen der Daten und Darstellung
Controller
1) initiiert
Änderung
der Daten
© A. Meier/M. Braschler/J. Zeman/K. Rege
26 von 62
Verschiedene Ereignisquelle
Viewer
2) benachrichtigt
über Datenänderung
School of Engineering
■ Graphisches Element als Ereignisquelle
■ Button, etc
Benutzereingabe
3) liest neue Daten und
stellt diese dar
Delegiere Verarbeitung
Ereignis
(Event)
Ereignisquelle
Model
erzeuge Ereignis
Objekt, z.B ActionEvent
Ereignisverarbeiter
verarbeitet z.B. in
Methode actionPerformed
■ Lesen der Daten via Getter-Methode von Model
■ model.getValue()
■ Model als Ereignisquelle
■ Zustandsänderung als Ereignis
■ Anzeigen
Zustandsänderung
■ repaint() aufrufen
Ereignisquelle (Model)
Ereignis
(Event)
Ereignisverarbeiter (View)
erzeuge Ereignis
Objekt
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
27 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
28 von 62
1) CircleModel Klasse grow() Methode
2a) Anmelden von View an CircleModel
■ Verwaltung von PropertyChangeListeners mit Klasse PropertyChangeSupport
import java.awt.event.*;
import java.beans.*;
import java.awt.event.*;
public class CircleModel
{
private int value;
public class CircleModel{
private int value;
private PropertyChangeSupport props;
public CircleModel(int value) {
this.value = value;
}
public CircleModel(int value) {
this.value = value;
props = new PropertyChangeSupport(this);
}
public void setValue(int val) {
value = val;
}
Anmeldemethode, dass an PropertyChangeEvents interessiert
public void grow() {
setValue(value+1);
}
Methode um
Werte zu ändern
public void addPropertyChangeListener(PropertyChangeListener list) {
props.addPropertyChangeListener(list);
}
}
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
29 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
2b) Benachrichtigung von View bei Änderung
3) Auslesen von Wert
■ Methode setValue anpassen, dass PropertyChangeEvent bei Änderung
■ Auslesen des Werts mittels getValue-Methode
30 von 62
ausgelöst wird;
public class CircleModel
{
………
firePropertyChange(String name, Object oldVal, Object newVal);
import java.beans.*;
import java.awt.event.*;
public int getValue() {
return value;
}
public class CircleModel
{
}
……
public void setValue(int val) {
old = value);
value = val;
props.firePropertyChange("value",old,val);
}
……
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
31 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
32 von 62
CircleModel komplett
Zusammenfassung: MVC
import java.beans.*;
import java.awt.event.*;
■ Model: der Datenbehälter
■ View: zur Darstellung der Daten
public class CircleModel
{
private int value;
PropertyChangeSupport props;
■ Controller: zur Verarbeitung von Benutzerereignis, Auslösen der Datenänderung
public CircleModel(int value) {
this.value = value;
props = new PropertyChangeSupport(this);
}
■ PropertyChangeSupport: Hilfsklasse für die Verarbeitung von Properties
■
■
■
public void setValue(int val) {
old = value;
value = val;
props.firePropertyChange("value",old,val);
}
PropertyChangeEvent: Event der geschickt wird
addPropertyChangeListener ()
firePropertyChange(String, Object, Object)
public int getValue() {return value;}
public void grow() {setValue(value+1);}
public void addPropertyChangeListener(PropertyChangeListener list){
props.addPropertyChangeListener(list);
}
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
33 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
34 von 62
AWT Komponenten
■ Mittels dem AWT und dessen Komponenten lassen sich einfache GUIs erstellen
■ primär für Applets
■ Im AWT Paket ist der Event Mechanismus definier: import java.awt.event.*
■ Dieser wird auch in Swing bzw. JFC verwendet
■
AWT (Abstract Windows Toolkit)
JFC enthält einen wesentlich reichhaltigeren Satz
von GUI Komponenten (-> später)
■ Verschiedenen graphischen Komponenten des AWT
■
■
■
■
Button
TextField
Label
ScrollBar
■List
■TextArea
■Checkbox
■Choice
(ComboBox)
■Canvas
■...
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
35 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
36 von 62
AWT Klassenhierarchie (vereinfacht)
Abstrakte Oberklasse: Component
■ Component ist die abstrakte
Object
gemeinsame
Oberklasse
Component
einfache
Komponenten
Oberklasse der meisten GUIKomponenten des AWT
Klassenhierarchie der GUIKomponenten:
Behälter für andere
Komponenten
■ Component enthält viele Methoden, die von den GUI
Komponenten geerbt bzw. überschrieben werden:
■ setBackground(Color farbe)
setzt Hintergrundfarbe einer Komponente auf farbe
■ setForeground(Color farbe)
setzt Vordergrundfarbe einer Komponent auf farbe
■ setFont(Font font)
setzt Font einer Komponente auf font
Button
Scrollbar
Checkbox
Choice
Label
Canvas
Container
■ Component
■
TextComponent
■
■
Panel
Hilfsklasse für
Checkbox
Textfield
TextArea
■
Applet
CheckboxGroup
BorderLayout
Hilfsklassen zur
Anordnungssteuerung
Frame
Dialog
■
■
FlowLayout
School of Engineering
■
BoxLayout
auf dem Desktop
darstellbare Behälter
© A. Meier/M. Braschler/J. Zeman/K. Rege
■
37 von 62
Button
Canvas
Choice
Container
■ Panel
■ Applet
Label
List
Scrollbar
TextComponent
■ TextArea
■ TextField
School of Engineering
■ Color getBackground()
gibt die entsprechenden Werte der Komponente aus
■ Color getForeground()
■ Font getFont()
■ paint(Graphics g)
zeichnet die Komponente
repaint()
veranlasst AWT, die Methode update() der Komponente
(sobald als möglich) aufzurufen
■ update()
löscht den Bildschirmausschnitt, der der Komponente
entspricht, und ruft dann paint() auf
■ setVisible(boolean b)
macht entsprechende Komponente (un)sichtbar
© A. Meier/M. Braschler/J. Zeman/K. Rege
38 von 62
Textkomponenten Oberklasse: TextComponent
■ ist abstrakte Oberklasse der Klassen TextField und TextArea:
TextComponent definiert verschiedene Methoden, die von TextField
und TextArea geerbt werden:
■
setEditable(boolean b)
■
boolean isEditable()
■
■
String getText()
Zeilenende ist jeweils mit "\n" markiert
setText(String Text)
markieren.
int getSelectionStart()
gibt Startindex des selektierten Textes zurück
■
int getSelectionEnd()
gibt EndIndex des selektierten Textes zurück
■
String getSelectedText()
gibt den selektierten Text selbst zurück
■
select(int startidx ,int endidx)
selektiert Text zwischen startidx und endidx
■
selectAll()
selektiert gesamten Text im Textfeld
■
addTextListener(Object lis)
registriert ein Objekt als TextListener bei der
Textkomponente. Das Listenerobjekt wird
informiert, sobald sich der Text in der
Textkomponente geändert hat. Der TextListener
muss dazu die Methode public void
textValueChanged(TextEvent e) deklarieren.
■
School of Engineering
macht die Textkomponente editierbar oder nicht, je
nach Wert von b
gibt zurück, ob Textkomponente editierbar ist
liest den ganzen Text aus dem Textfeld aus
setzt Text in das Textfeld. Zeilenumbrüche mit
© A. Meier/M. Braschler/J. Zeman/K. Rege
TextField, TextArea und Label
"\n"
39 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
40 von 62
TextField und TextArea
Textzeile (TextField)
■ Klassen TextField und TextArea sind Unterklassen der Klasse
TextComponent
■ TextField ist für einzeilige Eingaben (und Ausgaben) gedacht
■ Bei TextField nur eine Zeile eingebbar.
■ Der eingegebene Text kann beliebig editiert werden, bis die Eingabe durch
Drücken der Enter-Taste bestätigt wird
■ Bei TextArea Eingabe beliebiger Anzahl Zeilen möglich
■ Löst ActionEvents aus
■
TextArea hat 2 Scrollbars
■ Anwendungsbeispiel:
■ Deklaration eines Textfeldes (3 Möglichkeiten):
■
■
■
■
TextArea t = new TextArea();
TextArea t = new TextArea("1. Zeile\n2.Zeile");
erzeugt ein Textfeld mit den 2 Zeilen.
TextArea t = new TextArea(anzReihen, anzKolonnen);
■ Nützliche Methoden (zusätzlich zu denen, die in Klasse TextComponent
definiert sind):
■
■
■
■
insert(String text, int idx) fügt text an der Stelle idx ins Textfeld ein
replaceRange(String text, int startindex, int endindex)
ersetzt Text zwischen startindex und endindex des Textfeldes durch text
append(String text) hängt text am Ende des Textfeldes an
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
41 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Textzeile erzeugen
…Textfield: Demo-Applikation
■ Applet als ActionListener deklarieren.
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class L8_Textfeld_Waehlerkontrolle extends Applet implements ActionListener {
private TextField eingabe; // Instanzvariablen: GUI-Objekt(Komponente) Textfield
private int alter;
//
alter: ermöglicht Datenaustausch zw. 2 Methoden
■ TextField-Variable deklarieren: TextField eingabe;
■ Textzeile erzeugen: eingabe = new TextField(10);
■
10 bedeutet die maximale Anzahl angezeigter Zeichen
public void init() {
eingabe = new TextField(10);
add(eingabe);
eingabe.addActionListener(this);
}
■ Textzeile zu Applet hinzufügen: add(eingabe);
■ Applet als Listener registrieren: eingabe.addActionListener(this);
■ Um den Text in der Textzeile zu verarbeiten, stellt die Komponente
verschiedene Methoden zur Verfügung:
■
Aufbau GUI
Komponente instanzieren
zur GUI addieren
Ereignis-Listener addieren
public void actionPerformed(ActionEvent event) {
if (event.getSource() == eingabe){
alter = Integer.parseInt(eingabe.getText());
}
repaint();
}
■ Methode actionPerformed schreiben.
■
//
//
//
//
public void paint (Graphics g) {
g.drawString("Alter ist " + alter, 50, 80);
if (alter >= 18){
g.drawString("Stimmberechtigt", 50, 100);
else {
g.drawString("Zu jung!", 50,100); }
}
Text von der Textzeile einlesen: eingabe.getText()
Text in Textzeile schreiben: eingabe.setText("Text")
42 von 62
// Textfeld auslesen und wandeln
}
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
43 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
44 von 62
Label
■ Labels sind Beschriftungen mit einem fixen Text
■
Erbt nicht von TextComponent
■ Ein Label-Objekt kann mit folgender Anweisung erzeugt werden (als lokale
Variable):
Label labelVariable = new Label("Labeltext");
■
Labeltext ist der Text der Beschriftung
Scrollbar
■ Labels verhalten sich wie andere Komponenten (Scrollbar, Button, etc.)
■ Label erzeugen keine Ereignisse!
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
45 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Schieberegler (Scrollbar, Slider)
Schieberegler Graphik
■ Der Scrollbar kann durch das Verschieben des Balkens oder durch Drücken auf
die Pfeile betätigt werden. Dabei verschiebt er sich mit der konstanten
Schrittweite 1 pro Ereignis.
■ Beispiel: Programm ScrollbarValues
■ Beim Erzeugen eines Scrollbars kann die Ausrichtung des Scrollbars, der
Minimal- und Maximalwert, der Startwert sowie die Grösse der Schrittweite
angegeben werden
46 von 62
public void adjustmentValueChanged(AdjustmentEvent e) {
Graphics g = getGraphics();
currentX = slider.getValue();
g.drawLine(0, currentY, currentX, currentY);
currentY = currentY+5;
}
■ Im Gegensatz zu Buttons und Textzeilen erzeugen Scrollbar Ereignisse der
Klasse AdjustmentEvent
■ Scrollbar ruft bei jeder Verschiebung der Balkens die Methode
adjustmentValueChanged(AdjustmentEvent e) auf
■ Aktueller Wert kann mit der Methode getValue() abgefragt werden
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
47 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
48 von 62
Schieberegler
…Schieberegler : Anwendungsbeispiel
Scrollbar (Auszug aus der Klassenbibliothek: Constructor)
public class L8_Scrollbar extends Applet implements AdjustmentListener{
private Scrollbar slider;
// Instanzvariablen
private int sliderValue = 0;
public Scrollbar (int
int
int
int
int
Parameters:
orientation,
value,
visible,
minimum,
maximum)
public void init() {
// GUI aufbauen
setLayout(null);
// kein Layout -> Komponenten von Hand positioniert und skaliert
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 1, 100);
slider.setBounds(100,10, 200, 20); // Slider-Grösse. x,y,width, height
add(slider);
slider.addAdjustmentListener(this);
}
orientation - indicates the orientation of the scroll bar. (Scrollbar.HORIZONTAL,
or Scrollbar.VERTICAL)
value - the initial value of the scroll bar
visible - the size of the scroll bar's bubble, representing the visible portion
minimum - the minimum value of the scroll bar
maximum - the maximum value of the scroll bar
public void paint(Graphics g) {
g.drawString("Aktueller Schiebereglerwert: "+sliderValue, 100, 100);
g.setColor(Color.GREEN);
g.fillRect(100,150,sliderValue*2, 30);
// Slider-Wert als Balken
}
public void adjustmentValueChanged(AdjustmentEvent e){
sliderValue = slider.getValue();
repaint();
}
■ Beispiel: () Skript, Schieberegler.java)
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
49 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
50 von 62
Skalierung des Schiebereglerwertes
… Skalierung des Schiebereglerwertes
■ Problem: Bei der Verwendung von Scrollbar tritt häufig folgendes Problem
■ Beispiel: Der gewünschte Scrollbar-Bereich im Progamm InchesToCm soll
auf:
■
■
0.0-10.0 sein mit einer Schrittweite von 0.1
Man möchte mit dem Scrollbar beispielsweise Werte zwischen 0.0 und 10.0 in 0.1-Schritten
einstellen
Die kleinste Schrittweite bei einem Scrollbar ist aber 1, da nur int-Zahlen als Scrollbar-Werte
erlaubt sind
■ Minimum, Maximum und Inkrement des Scrollbars auf 0, 100 bzw. 1 setzen:
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100);
■ Ausgelesener Scrollbar-Wert jeweils durch 10 dividieren:
■ Lösung: Die vom Scrollbar zurückgegebenen Werte werden skaliert
sliderValue = (double) slider.getValue()/10;
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
51 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
52 von 62
Lernaufgabe (Lösung im Anhang)
Zwei Slider mit je einem Label für die Ausgabe
Ausgabe des Programms:
Einführung Anordnung, Layouts
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
53 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
54 von 62
Einfache Anordnung von GUI-Komponenten
Null Layout
■ Java ordnet die GUI Komponenten automatisch an (=Layout)
■ Mittels setLayout(null) kann der Layoutmanager entfernt werden
■ Wenn nichts anderes angegeben wird, werden die Komponenten in einem
Applet nach einem FlowLayout angeordnet
■ Wird kein Layout angegeben, dass müssen die Komponenten Komponenten von
Hand positioniert und skaliert werden
■ Layout definiert "Strategie", wie die Komponenten angeordnet werden
■
■
Die Komponenten werden zeilenweise zentriert aufgereiht
Wenn eine Zeile voll ist, werden die restlichen Komponenten auf einer neuen Zeile dargestellt
public void init() {
// GUI aufbauen
setLayout(null);
// kein Layout
slider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 1, 100);
slider.setBounds(100,10, 200, 20); // Slider-Grösse. x,y,width, height
add(slider);
slider.addAdjustmentListener(this);
}
■ FlowLayout nicht für "hochwertige" GUIs geeignet
■ z.B. FlowLayout skaliert die Scrollbars automatisch Æ werden sehr klein
Abhilfe: andere Layouts definieren (z.B. Border- oder GridLayout Æ später)
oder einfach "null"-Layout verwenden
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
55 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
56 von 62
Zusammenfassung
Anhang: Applet Methoden
Zusammenfassung der Methoden, die der Programmierer schreibt, um
die View und den Controller für ein Model bereitzustellen:
■ Ereignisse
■ Entwurf von interaktiven Anwendungen: Modell, View, Controller
■ AWT (Abstract Windows Toolkit)
■ TextField, TextArea und Label
Methode
Wird aufgerufen,
wenn
Aufgabe
init
das Applet gestartet
wird
1. Erzeugt die Objekte für das Modell
2. Erzeugt beliebige Widgets, die gebraucht
werden
actionPerformed
der Benutzer eine
Schaltfläche drückt
Handhabt das Ereignis, indem sie
Anweisungen an das Modell weitergibt
(Aufruf einer Methode im Modellobjekt)
paint
eine Veränderung
angezeigt werden soll
– das Fenster muss
neu gezeichnet wrdn.
Zeigt alles an, was im Fenster angezeigt
werden muss
■ Scrollbar
■ Einführung Anordnung, Layouts
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
57 von 62
Anhang: paint vs. repaint
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
Komponenten und Ereignisklassen des AWT
■ Es gibt einen entscheidenden Unterschied zwischen paint und repaint
Ereignisklassen
■ paint(): wird vom Programmierer zur Verfügung gestellt und vom Browser
aufgerufen
■ repaint(): wird von der Bibliothek zur Verfügung gestellt und vom
Programmierer aufgerufen
Events Generated by AWT
Components
This table lists the kinds of
events that each 1.1 AWT
component can generate.
Methode
Wird aufgerufen, wenn
Aufgabe
paint
der Fensterinhalt neu gezeichnet
werden muss
Zeichnet den Fensterinhalt
repaint
sich das Modell verändert hat und
deshalb die View des Models im
Fenster verändert werden muss
Informiert den Browser darüber, dass sich
etwas im Fenster verändert hat und dass es
deshalb neu gezeichnet werden muss
School of Engineering
58 von 62
© A. Meier/M. Braschler/J. Zeman/K. Rege
59 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
60 von 62
Listener Interfaces und Methoden des AWT
Anhang: Lösung
Listener
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
■ Um Events zu behandeln, muss das
entsprechende Listener Interface
implementiert werden
public class LabelDemo extends Applet implements AdjustmentListener {
private Scrollbar bar1, bar2;
private int bar1Value = 0, bar2Value = 0;
■ Um ein Listener Interface zu
implementieren, müssen alle in der
Tabelle aufgeführten Methods im Applet
programmiert werden
public void init() {
Label title1, title2;
title1 = new Label("up:"); add(title1);
bar1 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100); add(bar1);
bar1.addAdjustmentListener(this);
title2 = new Label("down:"); add(title2);
bar2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, 100); add(bar2);
bar2.addAdjustmentListener(this);
}
public void paint(Graphics g) {
g.drawString("UP value is " + bar1Value, 100, 100);
g.drawString("DOWN value is " + bar2Value, 100, 150);
}
public void adjustmentValueChanged(AdjustmentEvent e) {
bar1Value = bar1.getValue(); bar2Value = bar2.getValue();
repaint();
}
■ Bsp. ActionListener muss
actionPerformed(
ActionEvent e) implementieren
}
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
61 von 62
School of Engineering
© A. Meier/M. Braschler/J. Zeman/K. Rege
62 von 62
Herunterladen