• Keine Ergebnisse gefunden

14) Architektur interaktiver Systeme

N/A
N/A
Protected

Academic year: 2021

Aktie "14) Architektur interaktiver Systeme"

Copied!
68
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Softwaretechnologie, © Prof. Uwe Aßmann

Technische Universität Dresden, Fakultät Informatik 1

14) Architektur interaktiver Systeme

Prof. Dr. rer. nat. habil. Uwe Aßmann Institut für Software- und

Multimediatechnik

Lehrstuhl Softwaretechnologie Fakultät für Informatik

TU Dresden

Version 11-0.1, 14.05.11

1. Übersicht über die Architektur

2. Einführendes Beispiel für Java-AWT-Oberflächen 3. Ereignisgesteuerter

Programmablauf Play-In

4. Benutzungsoberflächen mit

Swing

(2)

Prof. U. Aßmann, Softwaretechnologie 2

Andere Literatur

[Herrmann] M. Veit, S. Herrmann. Model-View-Controller and Object Teams: A Perfect Match of Paradigms. Aspect-Oriented System

Development (AOSD) 2003, ACM Press

(3)

Softwaretechnologie, © Prof. Uwe Aßmann

Technische Universität Dresden, Fakultät Informatik 3

14.1 Kopplung von Graphischen Benutzeroberflächen (GUI) und Anwendungslogik

.. Bringe Ereignisse, “auslösende”

Fensterelemente (Sicht) und Modell

zusammen

(4)

Prof. U. Aßmann, Softwaretechnologie 4

Schichtenarchitektur

Benutzungsoberfläche - Teile des Kontextmodells

Window

Button

Menu

(Fachliches) Modell Teammitglied

Teambesprechung

Ablauf- steuerung

Datenhaltung z.B. relationale Datenbank

(5)

Prof. U. Aßmann, Softwaretechnologie 5

Schichtenarchitektur

Graphische

Benutzungsoberfläche (Fensteroberfläche,

Widget-Hierarchie)

Window

Button

Menu

(Fachliches) Modell

Teammitglied

Teambesprechung

Unsichtbare Ablauf- Steuerung

(Ereignis- Verwaltung)

Play-In

(asynchron)

Play-out

(synchron, aber multiple Sichten und pull-Steuerung)

(6)

Prof. U. Aßmann, Softwaretechnologie 6

Graphische Benutzungsoberflächen Graphical User Interfaces (GUI)

1980: Smalltalk-80-Oberfläche (Xerox)

1983/84: Lisa/Macintosh-Oberfläche (Apple)

1988: NextStep (Next)

1989: OpenLook (Sun)

1989: Motif (Open Software Foundation)

1987/91: OS/2 Presentation Manager (IBM)

1990: Windows 3.0 (Microsoft)

1995-2001: Windows 95/NT/98/2000/ME/XP (Microsoft)

1995: Java AWT (SunSoft)

1997: Swing Components for Java (SunSoft)

2002: SWT von Eclipse

2006: XAML, Silverlight (Microsoft)

Xswt, xswing, XUL (Mozilla) etc.

(7)

Prof. U. Aßmann, Softwaretechnologie 7

Programme mit GUI laufen in 2 Phasen

1) Aufbauphase: Aufbau der Fensteroberflächen (-fronten, widget hierarchies) durch Konstruktoraufrufe und Einfügen in

Fensterhierarchie (embodiment) 2) Reaktionsphase,

1) bei der die Benutzeraktionen vom System (Ereignisverwaltung) als Ereignisobjekte ins Programm gegeben werden (Play-In)

2) Bei der in der Anwendungslogik durchgeführten Aktionen die

Fensteroberfläche auf den neuesten Stand gebracht wird (Play-Out)

(8)

Prof. U. Aßmann, Softwaretechnologie 8

Widgets und Datenstrukturen

Fensterstrukturen sind hierarchisch (Einkapselung von Widgets)

Datenstruktur in Anwendung wird den Widget-Hierarchien zugeordnet

Screen-Buffer zeigt die Widget-Struktur bitweise ( paint() )

Screen Buffer

View 1 - Widget Tree 1 (Fenster-Struktur)

View 2 - Widget Tree 2 (Fenster-Struktur)

Modell: Datenstruktur in Anwendungslogik

(und Datenbank) widget-

Observer

jdk- Observer

(9)

Prof. U. Aßmann, Softwaretechnologie 9

Zusammenspiel der Widget-Struktur und der Anwendungslogik

Interaktive Anwendungen mit GUI laufen in Phasen:

1) Netzaufbau-Phase:

Aufbau der Fensterstrukturen des GUI (widget hierarchies)

Aufbau der Datenstrukturen in der Anwendungslogik (Modellstruktur)

Anschluß des GUI-Reaktionscodes auf Veränderungen der Modellstruktur (View wird Observer des Modells, Vorbereitung des Play-Out, callbacks)

Anschluß des Modell-Reaktionscode auf Benutzereingaben (Controller ist Observer der Widgets, Vorbereitung des Play-In)

2) Arbeitsphase (Reaktive Phase)

bei der die Benutzeraktionen vom System als Ereignisobjekte ins Programm gegeben werden, d.h. die Reaktionsobjekte des Modells als Listener

benachrichtigt und ausgeführt werden (Play-In)

Bei denen die GUI-Views auf Modelländerungen durch Neuanzeigen reagieren (Play-Out)

Der Steuerfluß eines GUI-Programms wird nie explizit spezifiziert, sondern ergibt sich aus den Aktionen des Benutzers

Das GUI-Programm reagiert nur (reaktives System)

(10)

Prof. U. Aßmann, Softwaretechnologie 10

Netzaufbauphase: Aufbau der Widget-Struktur

Verschiedene Techniken:

Durch Konstruktoraufrufe und Additionen von Unterwidgets zu Oberwidgets (encapsulation)

rein in Java-AWT/Swing, mit expliziter Konstruktion der Widget-Hierarchien

Durch einen XML-Baum, der von einem XML-Parser eingelesen und als Objekt-Struktur im Speicher abgelegt wird (XUL - Firefox, XAML - Vista)

Durch einen HTML-Baum, der von einem Brauser interpretiert wird (für Webanwendungen)

Durch einen HTML-Baum, der bei Veränderungen inkrementell im Brauser nachgeladen wird (Web 2.0, Ajax)

Screen Buffer

View 1 - Widget Tree 1 in html / Ajax

Modell: Datenstruktur in Anwendungslogik

(und Datenbank) Client Server

(11)

Softwaretechnologie, © Prof. Uwe Aßmann

Technische Universität Dresden, Fakultät Informatik 11

14.2 Einführendes Beispiel über

Play-In und Play-Out mit Java-AWT

(12)

Prof. U. Aßmann, Softwaretechnologie 12

Sichten: Zähler als motivierendes Beispiel

c: Counter ctr = 7

Counter + count() + reset() + getValue()

– ctr

Modell

cf: CounterFrame

Sicht 1

Sicht 2

(13)

Prof. U. Aßmann, Softwaretechnologie 13

Modell und Sicht

Methodenaufrufe

=> Änderungen (play-in, asynchron ausgelöst)

Beispiele: Verschiedene Dokumentenansichten, Statusanzeigen, Verfügbarkeit von Menüpunkten

Frage: Wie hält man das Modell in der Anwendungslogik unabhängig von den beliebig vielen Sichten darauf ?

Benachrichtigung vieler Sichten über Änderungen (play-out, synchron, viele Listener)

Fachliche Klasse (Modell)

Sicht 1

(View) Sicht 2

(View)

Muster "Observer"

Controller

(14)

Prof. U. Aßmann, Softwaretechnologie 14

Ein Zähler (Beispiel für fachliches Modell)

class Counter { private int ctr = 0;

public void count () { ctr++;

}public void reset () { ctr = 0;

}public int getValue () { return ctr;

} }

(15)

Prof. U. Aßmann, Softwaretechnologie 15

Beobachtbares Modell (Play out, Model)

class Counter extends Observable { private int ctr = 0;

public void count () { ctr++;

setChanged();

notifyObservers();

}

public void reset () { ctr = 0;

setChanged();

notifyObservers();

}

public int getValue () { return ctr;

} }

• Counter wird Subjekt im Muster Observer; bei Veränderung des Counter wird die Oberfl äche benachrichtigt (play out)

• Das fachliche Modell enthält keinerlei Bezug auf die Benutzungsoberfl äche

• Beliebig viele „Listener“ in Oberfl äche möglich

(16)

Prof. U. Aßmann, Softwaretechnologie 16

Hauptprogramm für Fensteranzeige

import java.awt.*;

class ExampleFrame extends Frame { public ExampleFrame () {

setTitle("untitled");

setSize(150, 50);

setVisible(true);

} }

class GUI1 {

public static void main (String[] argv) { // Phase 1: Aufbau der Fensteroberfläche

ExampleFrame f = new ExampleFrame();

// .. implizites Betreten der Reaktionsschleife:

// Phase 2: reaktives Programm

} }

(17)

Prof. U. Aßmann, Softwaretechnologie 17

Registrierung für Listener (Play-In)

Im „Auslöser“ java.awt.Frame findet sich eine

Registrierungsprozedur (ererbt von java.awt.Window):

public class Frame ... {

public void addWindowListener (WindowListener l)

}

java.awt.event.WindowListener ist eine Schnittstelle:

public interface WindowListener {

... Methoden zur Ereignisbehandlung }

Vergleich mit Observer-Muster:

Frame bietet einen "Observable (Subject)"-Mechanismus

Window-Listener ist eine "Observer"-Schnittstelle

Observer Observable (Subject)

Observing (Observer)

(18)

Prof. U. Aßmann, Softwaretechnologie 18

Hauptprogramm für schließbares Fenster (play-in)

import java.awt.*;

import java.awt.event.*;

class WindowCloser implements WindowListener { ... siehe später ...

}

class ExampleFrame extends Frame { public ExampleFrame () {

setTitle("untitled");

setSize(150, 50);

addWindowListener(new WindowCloser());

setVisible(true);

} }

class GUI2 {

public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();

} }

Anmelden

Subjekt starten

(Ereignisverwaltung)

reagieren (Phase 2)

(19)

Softwaretechnologie, © Prof. Uwe Aßmann

Technische Universität Dresden, Fakultät Informatik 19

I claim not to have controlled events,

but confess plainly that events have controlled me.

Abraham Lincoln, 1864

14.3 Ereignisgesteuerter

Programmablauf beim Play-In

Asynchroner Programmablauf

beim Play-In

(20)

Prof. U. Aßmann, Softwaretechnologie 20

Ereignisse

Ein Ereignis ist ein Vorgang in der Umwelt des Softwaresystems von vernachlässigbarer Dauer, der für das System von Bedeutung ist.

Eine wichtige Gruppe von Ereignissen sind Benutzeraktionen:

Drücken eines Knopfs

Auswahl eines Menüpunkts

Verändern von Text

Zeigen auf ein Gebiet

Schließen eines Fensters

Verbergen eines Fensters

Drücken einer Taste

Mausklick

(21)

Prof. U. Aßmann, Softwaretechnologie 21

Schliessknopf

Beispiel für Ereignisverarbeitung

Das erste Java-Programm in der Vorlesung mit einer

"graphischen Benutzungsoberfläche"...

Hinweis "für Java-Insider": Hier noch reines "AWT", im nächsten Kapitel wird "Swing" eingeführt werden.

• Aufgabe: Ein leeres, aber schliessbares Fenster anzeigen

Fensterdarstellung ("look and feel") gemäß Windows:

(22)

Prof. U. Aßmann, Softwaretechnologie 22

Ereignis-Klassen und ihre “auslösenden”

Oberflächenelemente

Ereignis-Klassen in (Java-)Benutzungsoberflächen:

WindowEvent

ActionEvent

MouseEvent

KeyEvent, ...

Bezogen auf Klassen für Oberflächenelemente

Window

Frame

Button

TextField, ...

Zuordnung (Beispiele):

Window (mit Frame) erzeugt WindowEvent

z.B. Betätigung des Schliessknopfes

Button erzeugt ActionEvent

bei Betätigung des Knopfes

(23)

Prof. U. Aßmann, Softwaretechnologie 23

Ereignis-Bearbeitung beim play-in (1)

Benutzer

Laufzeit-System (Ereignisverwaltung) betätigt Schliessknopf

Reaktion auf ein Ereignis durch Programm:

Ereignis wird vom Laufzeitsystem erkannt

Programm soll von technischen Details entkoppelt werden

Beobachter-Prinzip:

Programmteile registrieren sich für bestimmte Ereignisse

Laufzeitsystem sorgt für Aufruf an passender Stelle

Objekte, die Ereignisse beobachten, heißen bei Java Listener.

(24)

Prof. U. Aßmann, Softwaretechnologie 24

Ereignis-Bearbeitung beim play-in (2)

l: WindowListener

registriert bei

Delegation:

Aufruf einer Methode von l mit Argument e

e: WindowEvent Quelle

Benutzer

Laufzeit-System

betätigt Schliessknopf

f: Frame

vom System (Ereignisverw.) neu erzeugt:

(25)

Prof. U. Aßmann, Softwaretechnologie 25

Hierarchie der AWT EventListener (Widget- Listeners) und Event-Objekte

Die Vererbungshierarchien EventListener und AWTEvent werden parallel variiert

WindowListener TextListener

void TextValueChanged(TextEvent e) AWTEventListener

void eventDispatched(AWTEvent event)

ChangeListener

void stateChanged(ChangeEvent e)

WindowFocusListener

void windowGainedFocus(WindowEvent e) void windowLostFocus(WindowEvent e) EventListener

ActionListener

void actionPerformed(ActionEvent e) MenuListener

void menuSelected(MenuEvent e) void menuCancelled(MenuEvent e) void menuDeselected(MenuEvent e)

PropertyChangeListener

void propertyChange(PropertyChangeEvent evt)

WindowEvent TextEvent

ChangeEvent AWTEvent

ActionEvent

MenuEvent

PropertyChangeEvent EventObject

(26)

Prof. U. Aßmann, Softwaretechnologie 26

java.awt.event.WindowListener

/** empty marker interface, from which all listeners have to inherit */

public interface EventListener { };

public interface WindowListener extends EventListener {

public void windowClosed (WindowEvent ev);

public void windowOpened (WindowEvent ev);

public void windowIconified (WindowEvent ev);

public void windowDeiconified (WindowEvent ev);

public void windowActivated (WindowEvent ev);

public void windowDeactivated (WindowEvent ev);

public void windowClosing (WindowEvent ev);

}

java.util.EventListener:Basisinterface für alle "Listener"

(27)

Prof. U. Aßmann, Softwaretechnologie 27

Definition von Ereignissen:

java.awt.event.WindowEvent

public class WindowEvent extends AWTEvent { ...

// Konstruktor, wird vom System aufgerufen public WindowEvent (Window source, int id);

// Abfragemöglichkeiten

public Window getWindow();

...

}

(28)

Prof. U. Aßmann, Softwaretechnologie 28

java.awt.event.ActionEvent, ActionListener

public class ActionEvent extends AWTEvent { ...

// Konstruktor, wird vom System

// (Ereignisverwaltung) aufgerufen public ActionEvent

(Window source, int id, String command);

// Abfragemöglichkeiten

public Object getSource ();

public String getActionCommand();

...

}

public interface ActionListener extends EventListener {

public void actionPerformed (ActionEvent ev);

}

(29)

Prof. U. Aßmann, Softwaretechnologie 29

Wer reagiert denn hier auf Ereignisse?

Ereignis-Listener sind Schnittstellen, keine Implementierungsklassen

Wie programmiert man die Klassen, die die abhörenden Schnittstellen implementieren?

Eine neue Klasse (Implementierungsklasse)

Eine Default-Implementierung benutzen (WindowAdapter)

Eine Unterklasse der Default-Implementierung WindowAdapter

Eine innere Klasse

Eine anonyme Klasse

(30)

Prof. U. Aßmann, Softwaretechnologie 30

a) Implementierungsklasse WindowCloser für Ereignis "Schließen"

import java.awt.*;

import java.awt.event.*;

class WindowCloser implements WindowListener { // Reagiert nur auf Schließen

public void windowClosed (WindowEvent ev) {}

public void windowOpened (WindowEvent ev) {}

public void windowIconified (WindowEvent ev) {}

public void windowDeiconified (WindowEvent ev) {}

public void windowActivated (WindowEvent ev) {}

public void windowDeactivated (WindowEvent ev) {}

public void windowClosing(WindowEvent event) { System.exit(0);

}

}

(31)

Prof. U. Aßmann, Softwaretechnologie 31

Hauptprogramm für schließbares Fenster

import java.awt.*;

import java.awt.event.*;

class WindowCloser implements WindowListener { ... siehe vorige Folie ...

}

class ExampleFrame extends Frame { public ExampleFrame () {

setTitle("untitled");

setSize(150, 50);

addWindowListener(new WindowCloser());

setVisible(true);

} }

class GUI2 {

public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();}

}

(32)

Prof. U. Aßmann, Softwaretechnologie 32

b) Vereinfachung 1: Unterklasse der Default- Implementierung WindowAdapter

WindowAdapter bietet eine Default-Implementierung für die WindowListener-Funktionen an:

package java.awt.event;

public abstract class WindowAdapter implements WindowListener {

public void windowClosed (WindowEvent ev) {}

public void windowOpened (WindowEvent ev) {}

public void windowIconified (WindowEvent ev) {}

public void windowDeiconified (WindowEvent ev) {}

public void windowActivated (WindowEvent ev) {}

public void windowDeactivated (WindowEvent ev) {}

public void windowClosing (WindowEvent ev) {}

}

(33)

Prof. U. Aßmann, Softwaretechnologie 33

Vereinfachung 1: Unterklasse der Default- Implementierung WindowAdapter

Redefinition einer leeren Reaktionsmethode:

import java.awt.*;

import java.awt.event.*;

class WindowCloser extends WindowAdapter {

public void windowClosing(WindowEvent event) { System.exit(0);

} }

class ExampleFrame extends Frame { public ExampleFrame () {

setTitle("untitled");

setSize(150, 50);

addWindowListener(new WindowCloser());

setVisible(true);

} }

class GUI3 {

public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();}

}

(34)

Prof. U. Aßmann, Softwaretechnologie 34

Vereinfachung 1: Unterklasse der

DefaultImplementierung WindowAdapter

WindowCloser registriert bei

Frame

ExampleFrame setSize

setTitle setVisible

Window

addWindowListener (l: WindowListener)

<<interface>>

WindowListener

windowClosing (e: WindowEvent)

WindowEvent

<<use>>

WindowAdapter

(35)

Prof. U. Aßmann, Softwaretechnologie 35

Diskussion zum Begriff "Adapter"

<<interface>>WindowListener

windowClosing (e: WindowEvent) window... ()...

...

WindowAdapter

Adapter

WindowCloser

windowClosing (e: WindowEvent)

Ist das eine Anwendung des Adapter-Musters?

Target Adaptee

Adapter

.. sollte besser

DefaultWindowListener heissen..

(36)

Prof. U. Aßmann, Softwaretechnologie 36

b) Vereinfachung 2: Innere Klasse benutzen

import java.awt.*;

import java.awt.event.*;

class ExampleFrame extends Frame {

/* inner */ class WindowCloser extends WindowAdapter { public void windowClosing(WindowEvent event) {

System.exit(0);

} }

public ExampleFrame () { setTitle("untitled");

setSize(150, 50);

addWindowListener(new WindowCloser());

setVisible(true);

} }

class GUI4 {

public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();}}

(37)

Prof. U. Aßmann, Softwaretechnologie 37

c) Vereinfachung 3: Anonyme Klasse benutzen

import java.awt.*;

import java.awt.event.*;

class ExampleFrame extends Frame { public ExampleFrame () {

setTitle("untitled");

setSize(150, 50);

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent event) { System.exit(0);

}});

setVisible(true);

} }

class GUI5 {

public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();

}}

(38)

Softwaretechnologie, © Prof. Uwe Aßmann

Technische Universität Dresden, Fakultät Informatik 38

14.4 Aufbau der Benutzungsoberfläche

(Widget-Hierarchie) mit Swing

(39)

Prof. U. Aßmann, Softwaretechnologie 39

Hier: Expliziter Aufbau mit AWT und Swing

Abstract Window Toolkit (AWT):

Seit Version 1.1 Standard-Bestandteil von Java

Umfangreiche Bibliothek von Oberflächen-Bausteinen

Plattformunabhängige Schnittstellen, aber grosse Teile plattformspezifisch realisiert ("native code")

Swing-Bibliotheken

Seit Version 1.2 Standard-Bestandteil von Java

Noch umfangreichere Bibliothek von Oberfächen-Bausteinen

Plattformunabhängiger Code

(d.h. Swing ist weitestgehend selbst in Java realisiert)

Wesentlich größerer Funktionsumfang

(nicht auf den "kleinsten Nenner" der Plattformen festgelegt)

(40)

Prof. U. Aßmann, Softwaretechnologie 40

Bibliotheken von AWT und Swing

Wichtigste AWT-Pakete:

java.awt: u.a. Grafik, Oberflächenkomponenten, Layout-Manager

java.awt.event: Ereignisbehandlung

Andere Pakete für weitere Spezialzwecke

Wichtigstes Swing-Paket:

javax.swing: Oberflächenkomponenten

Andere Pakete für Spezialzwecke

Viele AWT-Klassen werden auch in Swing verwendet!

Standard-Import-Vorspann:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

(Naiver) Unterschied zwischen AWT- und Swing-Komponenten:

AWT: Button, Frame, Menu, ...

Swing: JButton, JFrame, JMenu, ...

(41)

Prof. U. Aßmann, Softwaretechnologie 41

AWT/Swing-Klassenhierarchie (Ausschnitt)

lang.Object awt.Component

awt.Container

swing.JComponent awt.Window

swing.

JFrame swing.

JTextField swing.

JLabel swing.

JButton swing.

JPanel swing.

JTextComponent

Dies ist nur ein sehr kleiner Ausschnitt

Präfixe "java." und "javax." hier weggelassen.

(42)

Prof. U. Aßmann, Softwaretechnologie 42

Component, Container, Window, Frame, Panel

awt.Component (abstrakt):

Oberklasse aller Bestandteile der Oberfläche

public void setSize (int width, int height);

public void setVisible (boolean b);

awt.Container (abstrakt):

Oberklasse aller Komponenten, die andere Komponenten enthalten

public void add (Component comp);

public void setLayout (LayoutManager mgr);

awt.Window

Fenster ohne Rahmen oder Menüs

public void pack (); //Größe anpassen

swing.JFrame

Größenveränderbares Fenster mit Titel

public void setTitle (String title);

swing.JPanel

Zusammenfassung von Swing-Komponenten

Component Container

Window JFrame JPanel

(43)

Prof. U. Aßmann, Softwaretechnologie 43

JComponent

Oberklasse aller in der Swing-Bibliothek neu implementierten, verbesserten Oberflächenkomponenten. Eigenschaften u.a.:

Einstellbares "Look-and-Feel"

Komponenten kombinierbar und erweiterbar

Rahmen für Komponenten

void setBorder (Border border);

(Border-Objekte mit BorderFactory erzeugbar)

ToolTips -- Kurzbeschreibungen, die auftauchen, wenn der Cursor über der Komponente liegt

void setToolTipText (String text);

Automatisches Scrolling

Beispiele für weitere Unterklassen von JComponent:

JList: Auswahlliste

JComboBox: "Drop-Down"-Auswahlliste mit Texteingabemöglichkeit

JPopUpMenu: "Pop-Up"-Menü

JFileChooser: Dateiauswahl

Component Container JComponent

(44)

Prof. U. Aßmann, Softwaretechnologie 44

Zähler-Beispiel: Grobentwurf der Oberfläche

CounterFrame cf abgeleitet von JFrame

JPanel valuePanel

JPanel

buttonPanel

(45)

Prof. U. Aßmann, Softwaretechnologie 45

Die Sicht (View) mit Swing:

Gliederung, 1. Versuch

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

// .. value panel hinzufügen

getContentPane().add(valuePanel, BorderLayout.NORTH);

buttonPanel.add(countButton);

buttonPanel.add(resetButton);

buttonPanel.add(exitButton);

// .. button panel hinzufügen

getContentPane().add(buttonPanel, BorderLayout.SOUTH);

pack();

setVisible(true);

}}

Subjekt starten

(Ereignisverwaltung)

(46)

Prof. U. Aßmann, Softwaretechnologie 46

Hinzufügen von Komponenten zu JFrames

Ein JFrame ist ein "Container", d.h. dient zur Aufnahme weiterer Elemente.

Ein JFrame ist intern in verschiedene "Scheiben" (panes) organisiert. Die wichtigste ist die content pane.

• In JFrame ist definiert:

Container getContentPane();

glass panemenu barlayered panecontent pane

(47)

Prof. U. Aßmann, Softwaretechnologie 47

Die Sicht (View): Gliederung, 2. Versuch

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JPanel buttonPanel = new JPanel();

public CounterFrame (Counter c) { setTitle("SwingCounter");

getContentPane().add(valuePanel);

getContentPane().add(buttonPanel);

pack();

setVisible(true);

}}

(48)

Prof. U. Aßmann, Softwaretechnologie 48

Zähler-Beispiel: Entwurf der Wertanzeige

JPanel valuePanel

JLabel

valueLabel JTextField

valueDisplay

(49)

Prof. U. Aßmann, Softwaretechnologie 49

TextComponent, TextField, Label, Button

JTextComponent:

Oberklasse von JTextField und JTextArea public void setText (String t);

public String getText ();

public void setEditable (boolean b);

JTextField:

Textfeld mit einer Zeile

public JTextField (int length);

JLabel:

Einzeiliger unveränderbarer Text public JLabel (String text);

JButton:

Druckknopf mit Textbeschriftung

public JButton (String label);

Component Container JComponent

JTextComponent JTextField

JLabel JButton

(50)

Prof. U. Aßmann, Softwaretechnologie 50

Die Sicht (View): Elemente der Wertanzeige

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

getContentPane().add(valuePanel);

getContentPane().add(buttonPanel);

pack();

setVisible(true);

}}

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

getContentPane().add(valuePanel);

getContentPane().add(buttonPanel);

pack();

setVisible(true);

}}

(51)

Prof. U. Aßmann, Softwaretechnologie 51

Zähler-Beispiel: Entwurf der Bedienelemente

JPanel buttonPanel

JButton

countButton JButton

resetButton JButton

exitButton

(52)

Prof. U. Aßmann, Softwaretechnologie 52

Die Sicht (View): Bedienelemente

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

getContentPane().add(valuePanel);

buttonPanel.add(countButton);

buttonPanel.add(resetButton);

buttonPanel.add(exitButton);

getContentPane().add(buttonPanel);

pack();

setVisible(true);

}}

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

getContentPane().add(valuePanel);

buttonPanel.add(countButton);

buttonPanel.add(resetButton);

buttonPanel.add(exitButton);

getContentPane().add(buttonPanel);

pack();

setVisible(true);

}}

(53)

Prof. U. Aßmann, Softwaretechnologie 53

Layout-Manager

Definition Ein Layout-Manager ist ein Objekt, das Methoden bereitstellt, um die graphische Repräsentation verschiedener Objekte innerhalb eines Container-Objektes anzuordnen.

Formal ist LayoutManager ein Interface, für das viele Implementierungen möglich sind.

In Java definierte Layout-Manager (Auswahl):

FlowLayout (java.awt.FlowLayout)

BorderLayout (java.awt.BorderLayout)

GridLayout (java.awt.GridLayout)

In awt.Component:

public void add (Component comp, Object constraints);

erlaubt es, zusätzliche Information (z.B. Orientierung, Zeile/Spalte)

an den Layout-Manager zu übergeben

(54)

Prof. U. Aßmann, Softwaretechnologie 54

Flow-Layout

Grundprinzip:

Anordnung analog Textfluß:

von links nach rechts und von oben nach unten

Default für Panels

z.B. in valuePanel und buttonPanel

für Hinzufügen von Labels, Buttons etc.

Parameter bei Konstruktor: Orientierung auf Zeile, Abstände

Constraints bei add : keine

1 2 3 4 5

6

(55)

Prof. U. Aßmann, Softwaretechnologie 55

Border-Layout

Grundprinzip:

Orientierung nach den Seiten (N, S, W, O) bzw. Mitte (center)

Default für Window, Frame

z.B. in CounterFrame

für Hinzufügen von valuePanel, buttonPanel

Parameter bei Konstruktor: Keine

Constraints bei add:

BorderLayout.NORTH, SOUTH, WEST, EAST, CENTER

Oberer ("Nord")-Bereich (z.B. valuePanel)

Unterer ("Süd")-Bereich

(z.B. buttonPanel)

(56)

Prof. U. Aßmann, Softwaretechnologie 56

Grid-Layout

Grundprinzip:

Anordnung nach Zeilen und Spalten

Parameter bei Konstruktor:

Abstände, Anzahl Zeilen, Anzahl Spalten

Constraints bei add: Keine

1,1 1,2 1,3

2,1 2,2 2,3

(57)

Prof. U. Aßmann, Softwaretechnologie 57

class CounterFrame extends JFrame { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

getContentPane().add(valuePanel, BorderLayout.NORTH);

buttonPanel.add(countButton);

buttonPanel.add(resetButton);

buttonPanel.add(exitButton);

getContentPane().add(buttonPanel, BorderLayout.SOUTH);

pack();

setVisible(true);

}}

Die Sicht (View): Alle sichtbaren Elemente

(58)

Prof. U. Aßmann, Softwaretechnologie 58

Model-View-Controller-Architektur

c: Counter ctr = 7

Counter

+ count() + reset() + getValue()

– ctr

Model

cf: CounterFrame View

<<beobachtet>>

bc: ButtonController Controller

<<steuert>>

<<beobachtet>>

GUI-Reagiert-Auf-Modelländerungen: Observer (Play-Out)

Modell-Reagiert-Auf-View: Controller (Play-In)

Play-Out

Play-In

(59)

Prof. U. Aßmann, Softwaretechnologie 59

Zähler-Beispiel für das Play-Out:

Anbindung View an Model

class CounterFrame extends JFrame // View implements Observer {

...

JTextField valueDisplay = new JTextField(10);

...

// connecting model to view

public CounterFrame /*View*/ (Counter c /*Model*/) { ...

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

valueDisplay.setText(String.valueOf(c.getValue()));

...

c.addObserver(this); // Registring view at model pack();

setVisible(true);

} // view listens at model

public void update (Observable o, Object arg) { Counter c = (Counter) o;

valueDisplay.setText(String.valueOf(c.getValue()));

}}

(60)

Prof. U. Aßmann, Softwaretechnologie 60

Wdh: java.awt.event.ActionEvent, ActionListener

public class ActionEvent extends AWTEvent { ...

// Konstruktor wird vom System aufgerufen public Object getSource ()

public String getActionCommand() ...

}

public interface ActionListener extends EventListener {

public void actionPerformed (ActionEvent ev);

}

(61)

Prof. U. Aßmann, Softwaretechnologie 61

// Die Steuerung belauscht die Knöpfe class ButtonController // Controller implements ActionListener {

Counter myCounter;

// widget-Observer

public void actionPerformed (ActionEvent event) { String cmd = event.getActionCommand();

if (cmd.equals("Count"))

myCounter.count(); // Aktion auf Modell if (cmd.equals("Reset"))

myCounter.reset(); // Aktion if (cmd.equals("Exit"))

System.exit(0); // Aktion }

public ButtonController (Counter c) { myCounter = c;

}}

// Die Steuerung belauscht die Knöpfe class ButtonController // Controller implements ActionListener {

Counter myCounter;

// widget-Observer

public void actionPerformed (ActionEvent event) { String cmd = event.getActionCommand();

if (cmd.equals("Count"))

myCounter.count(); // Aktion auf Modell if (cmd.equals("Reset"))

myCounter.reset(); // Aktion if (cmd.equals("Exit"))

System.exit(0); // Aktion }

public ButtonController (Counter c) { myCounter = c;

}}

Die Steuerung des Play-In mit dem Controller

Zum Play-In wird der Controller ein Listener der View-Widgets (hier buttons)

Die update-Methode heisst actionPerformed(ActionEvent), da die Ablaufsteuerung des JDK diese sucht und aufruft

(62)

Prof. U. Aßmann, Softwaretechnologie 62

Play-In, Zähler-Beispiel: Anbindung des Controllers an mehrere Views (Subjekte)

class CounterFrame extends JFrame { ...

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { ...

ButtonController bc = new ButtonController(c);

// controller listens at another view countButton.addActionListener(bc);

buttonPanel.add(countButton);

// controller listens at another view resetButton.addActionListener(bc);

buttonPanel.add(resetButton);

// controller listens at another view exitButton.addActionListener(bc);

buttonPanel.add(exitButton);

...

}}

(63)

Prof. U. Aßmann, Softwaretechnologie 63

Alles zusammen: CounterFrame (1)

class CounterFrame extends JFrame implements Observer { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

valueDisplay.setText(String.valueOf(c.getValue()));

getContentPane().add(valuePanel,BorderLayout.NORTH );ButtonController bc = new ButtonController(c);

countButton.addActionListener(bc);

buttonPanel.add(countButton);

resetButton.addActionListener(bc);

buttonPanel.add(resetButton);

exitButton.addActionListener(bc);

buttonPanel.add(exitButton);

getContentPane().add(buttonPanel,BorderLayout.SOUTH);

class CounterFrame extends JFrame implements Observer { JPanel valuePanel = new JPanel();

JTextField valueDisplay = new JTextField(10);

JPanel buttonPanel = new JPanel();

JButton countButton = new JButton("Count");

JButton resetButton = new JButton("Reset");

JButton exitButton = new JButton("Exit");

public CounterFrame (Counter c) { setTitle("SwingCounter");

valuePanel.add(new JLabel("Counter value"));

valuePanel.add(valueDisplay);

valueDisplay.setEditable(false);

valueDisplay.setText(String.valueOf(c.getValue()));

getContentPane().add(valuePanel,BorderLayout.NORTH );ButtonController bc = new ButtonController(c);

countButton.addActionListener(bc);

buttonPanel.add(countButton);

resetButton.addActionListener(bc);

buttonPanel.add(resetButton);

exitButton.addActionListener(bc);

buttonPanel.add(exitButton);

getContentPane().add(buttonPanel,BorderLayout.SOUTH);

(64)

Prof. U. Aßmann, Softwaretechnologie 64

Alles zusammen: CounterFrame (2)

addWindowListener(new WindowCloser());

c.addObserver(this);

pack();

setVisible(true);

}

public void update (Observable o, Object arg) { Counter c = (Counter) o;

valueDisplay.setText(String.valueOf(c.getValue()));

} }

class ButtonController implements ActionListener { ... (wie oben) ...

}

class WindowCloser implements WindowListener { ... (wie oben) ...

}

(65)

Prof. U. Aßmann, Softwaretechnologie 65

c:Controller c:Controller

Überblick MVC

c:Controller

v:View v:View v:View

m:Model 1

*

1 1

*

1

[Herrmann]

change messages observer

change messages observer user input observer

direct change messages

model read model

change

{xor}

{xor}

(66)

Prof. U. Aßmann, Softwaretechnologie 66

Probleme im MVC

Wiederverwendung von Sichten und Controller – wie?

Modell ist abstrakte Klasse (white-box framework mit Variationspunkt Modell)

Sicht ist Rolle der Modellklasse (open role framework)

Granularität der Ereignisse:

Welche Änderungen des Modells sollen en-bloc von Sichten übernommen werden?

(67)

Prof. U. Aßmann, Softwaretechnologie 67

Was haben wir gelernt?

GUI-Programme laufen in 2 Phasen:

Aufbau der Fensterfronten (widget hierarchies) durch Konstruktoraufrufe und Additionen (embodiment)

Vorbereitung Play-Out: Anschluß des View-Reaktionscodes als jdk-Observer des Modells

Vorbereitung Play-In: Anschluß des Controller als widget-Observer der Views

Reaktionsphase, bei der die Benutzeraktionen vom System als Ereignisobjekte ins Programm gegeben werden:

der Controller als Listener benachrichtigt und ausgeführt werden (Play-In)

die Views bzw. der Controller als Listener des Modells benachrichtigt werden (Play-Out)

Der Kontrollfluß eines GUI-Programms wird nie explizit spezifiziert, sondern ergibt sich aus den Aktionen des Benutzers

Die Views reagieren auf Ereignisse im Screenbuffer, die von der Ablaufsteuerung gemeldet werden

Der Controller auf Widget-Veränderungen im View

Die Views auf Veränderungen im Modell

(68)

Prof. U. Aßmann, Softwaretechnologie 68

The End

Diese Folien sind eine überarbeitete Version der Vorlesungsfolien zur Vorlesung Softwaretechnologie von © Prof. H. Hussmann, 2002.

used by permission. Verbreitung, Kopieren nur mit Zustimmung des

Autors.

Referenzen

ÄHNLICHE DOKUMENTE

The appointments of General Chang Wanquan former Director of the PLA’s General Armaments Department (GAD) as Defence Minister and General Zhang Youxia, the sole battle-

public class MehrereButtons extends JFrame { private JPanel contentPane;. private boolean flag_enable

As one directly sees, the theory of monogenic au- tomorphic forms fits as a special case within the general framework of k-holomorphic Cliffordian automorphic forms.. Then, as stated

Fall, also einer Fehler-Kante von einem Dateneingabeknoten auf ein anderes Ereignis (s. Abbildung 5), darf das Nachfolgeereignis unabhängig von den eingegebenen Daten nicht

Mithilfe dieses Kommunikations-Cockpit soll es dem Planer möglich sein, Diskussionen zu steuern, Entscheidungen mit Gesetzestexte zu verlinken, so dass eine breiteres Verständnis

In this work, we aim to prove results for the problems (1)–(3) for a wider class of kernel-functions than introduced in [13]. In Chapter 2 we will extend the class of

Der kleinste gemeinsame Nenner an tatsächlich er- forderlichen Artefakten ist der Aus- gangspunkt für eine agile, interdiszipli- näre Werkzeugunterstützung (Tabelle

Die Klasse Spielfeld soll von JPanel abgeleitet werden und kann somit zu einem JFrame, also dem Spielfenster hinzugefügt werden.. Die Klasse Spielfeld soll auf