Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 21: GUI und verschachtelte.

Ähnliche Präsentationen


Präsentation zum Thema: "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 21: GUI und verschachtelte."—  Präsentation transkript:

1 Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 21: GUI und verschachtelte Klassen Prof. Dr. Max Mühlhäuser Dr. Guido Rößling

2 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 AWT und Swing AWT = Abstract Window Toolkit –Package java.awt –Benutzt Steuerelemente des darunterliegenden Betriebssystems Native Code (= direkt für die Maschine geschrieben, keine VM) schnell Aussehen (Look) hängt vom System ab: unterschiedliche Schriften, … Portabilität eingeschränkt Swing –Package javax.swing (Teil der Java Foundation Classes) –Merkmal: Swing-Klassen beginnen mit J: JButton,... –Vollständig in Java programmiert, eigener Look –Baut auf AWT auf –Verwendet ein Minimum an systemspezifischen Komponenten 2

3 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Komponenten Einige oft verwendete Komponenten und für welche Interaktionsaufgaben sie verwendet werden Anzeigen von Text und Symbolen –JLabel Auslösen von Aktionen –JButton –JMenu 3

4 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Komponenten Eingabe von Text –JTextField Auswahl aus einer festen Menge von Optionen –JCheckBox Auswahl aus einer variablen Menge –JList 4 gegenseitig ausschließend: JRadioButton JComboBox Button oder TextField + ausklappbare Listbox

5 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Menschliche Faktoren Beim Entwurf interaktiver Programme gibt es neben der funktionalen Vollständigkeit und Korrektheit viele zusätzliche Aspekte zu beachten Dazu gehört die Art und Weise der Interaktion und wie leicht sie zu erlernen und benutzen ist Richtlinien für gute GUIs sind u.a.: –Vermeide Modi. Allgemein sinnvolle Operationen sollten immer verfügbar sein. –Biete einfache und durchgängige Interaktionssequenzen an. –Überfordere den Benutzer nicht durch zu viele Optionen. –Zeige bei jeder Interaktionsstufe klar die verfügbaren Optionen. –Gib dem Benutzer angemessene Rückmeldungen. –Gib dem Benutzer die Möglichkeit, Fehler problemlos rückgängig zu machen. 5

6 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Anatomie einer GUI-Applikation Komponenten Container Ereignisse Listener Layout –Legt die Anordnung der Komponenten fest Look & Feel –Legt das Aussehen der Komponenten fest getrennt: Anwendungslogik 6 Anwendungslogik Zustand: wert=3 GUI-Framework Ereignisse Methodenaufrufe auf Komponente Komponenten Container Listener Netz von kooperierenden Objekten mit klar festgelegten Zuständigkeiten:

7 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Fäden (Threads) Sequentielle Programme –haben Anfang, definierte Ausführungssequenz und Ende. –Zu jedem Zeitpunkt ist genau eine Anweisung aktiv. –Ein Faden (Thread) ist ein einzelner sequentieller Kontrollfluss in einem Programm. Nebenläufige Programme –Programme können mehrere Fäden besitzen. –Mehrere Programmteile können so quasi gleichzeitig ablaufen. 7 Faden Programm Fäden Programm

8 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Fäden (Threads) Fäden (Threads)… –nutzen die Ressourcen des Prozesses mit, in dem sie ablaufen –besitzen keine eigenen Speichersegmente –verfügen über einen eigenen Registersatz (incl. Programmzähler und Statusregister) sowie einen eigenen Stack –werden oft auch als leichtgewichtige Prozesse (lightweight processes) bezeichnet. GUI-Applikationen besitzen neben dem Haupt-Thread einen sogenannten Event-Dispatching Thread –Dieser Thread ruft Methoden der Anwendung auf, wenn bestimmte Ereignisse auftreten (Callback) –Die Ereignisbehandlungsroutinen in der Anwendung werden sequentiell ausgeführt –Das Zeichnen von Komponenten wird ebenfalls im Kontext dieses Threads ausgeführt 8

9 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 AWT-EventQueue main Programmiermodell 9 AnwendungGUI-Framework (SWING) Komponente einfügen Ereignis: Komponente zeichnen Ereignis: Benutzereingabe main

10 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Fenster import javax.swing.JFrame; public class GUITest extends JFrame { // The height of the window in pixels public static final int WIDTH = 400; // The width of the window in pixels public static final int HEIGHT = 300; // Constructs a new window with a given title public GUITest(String title) { super(title); } // Start test application. Creates a new window and displays it public static void main(String args[]) { // Construct a new window. It is initially invisible GUITest theWindow = new GUITest("My first GUI Application"); // Set width and height of the window theWindow.setSize(WIDTH, HEIGHT); // Open the window theWindow.setVisible(true); System.out.println("Exiting main..."); } 10

11 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Fenster Wir beobachten... –main() wird verlassen, das Programm läuft aber weiter. Mehrere Fäden. Der Event-Dispatching Thread läuft weiter. –Klick auf Schließen-Button beendet das Programm nicht. Ereignisverarbeitung fehlt. Genaueres dazu später. 11

12 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Container Container und Komponenten –JFrame: top level container benutzt Fenster vom Betriebssystem –JPanel: intermediate container dient zum Gruppieren und Anordnen von Komponenten Verschachtelung möglich –JLabel, JButton,...: atomare Komponenten präsentieren dem Benutzer Informationen erlauben oft Interaktion und Eingabe (Steuerelemente) Container-Hierarchie –Selbst die einfachste Anwendung besteht aus einer Hierarchie von Containern und Komponenten –(Darstellung vereinfacht. Die Container zwischen JFrame und JPanel werden hier nicht weiter betrachtet) 12 JFrame JPanel JLabel JFrame JPanel JLabel...

13 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Komponenten Hinzufügen von Komponenten –Der JFrame erzeugt automatisch ein JPanel, das contentPane. –Darin kann die Anwendung neue Komponenten einfügen. –Die Komponenten werden eingefügt, während das Fenster noch unsichtbar ist, also zwischen dem Erstellen des Fenster-Objekts mit new und dem Öffnen mit setVisible(true). JLabels –stellen Text oder/und Symbole dar –sind passive Komponenten, erlauben keine Interaktion 13 JFrame JPanel JLabel... contentPane

14 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { public GUITest(String title) { super(title); // Retrieve the area where one can add elements Container pane = getContentPane(); // Create a new label that displays help information JLabel label = new JLabel( "Press the [X] in the top right corner to exit"); // Add the label to the content of the window pane.add(label); } //... } Labels 14

15 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Buttons import java.awt.Container; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { public GUITest(String title) { super(title); Container pane = getContentPane(); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); // Create a new push button that may be used in addition to the [X] JButton button = new JButton("Exit"); // Add the button to the content of the window pane.add(button); } //... } 15

16 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Layout Wir beobachten... –Der Text ist nicht mehr sichtbar, denn der Button liegt darüber! Layout-Management –ist der Prozess, die Größe und Position von Komponenten zu bestimmen. –Das gewünschte Layout wird durch Zuordnung eines Layout- Objekts zum Container festgelegt: Container pane = getContentPane(); pane.setLayout(new GridLayout(ROWS, COLS)); –Die Layout-Klasse implementiert das Interface LayoutManager. 16

17 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Vordefinierte Layouts GridLayout –Ordnet die Komponenten in einem rechteckigen Gitter an. –Die Reihenfolge des Einfügens der Komponenten bestimmt ihre Anordnung. BorderLayout –Positioniert in 5 Regionen jeweils maximal eine Komponente –Die Regionen N, E, S und W werden so klein wie möglich gehalten. Der restliche Platz entfällt auf CENTER. –Zuordnung zu einer Region durch zusätzlichen Parameter beim Aufruf von Container.add : add(new Button("SOUTH"), BorderLayout.SOUTH); Weitere Layouts: BoxLayout, FlowLayout, GridBagLayout,... –Siehe die Java API Dokumentation und die Tutorials für mehr Informationen 17

18 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 GridLayout import java.awt.Container; import java.awt.GridLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { public GUITest(String title) { super(title); Container pane = getContentPane(); // Define a LayoutManager that places new elements properly // onto the pane. Here we use a grid with 3 rows and 1 column. pane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); JButton button = new JButton("Exit"); pane.add(button); }... } 18

19 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Ereignisse (Events) Jedesmal, wenn der Benutzer eine Taste drückt oder die Maus bewegt, tritt ein Ereignis auf. Steuerelemente können Maus- und Tastatur-Ereignisse verarbeiten und neue Ereignisse erzeugen. –Beispiel: Befindet sich der Mauszeiger über einem Button und die Maustaste wird losgelassen, dann wird ein ActionEvent erzeugt. Ereignisse werden durch Event-Objekte beschrieben –Die zugehörigen Klassen sind von java.awt.AWTEvent abgeleitet. (für GUI; allgemeiner: java.util.EventObject ) –Der Typ gibt Auskunft über die Art des Ereignisses: ActionEvent :Benutzer klickt einen Button, drückt Return in einem Textfeld, wählt einen Menüeintrag,... WindowEvent :Benutzer schließt Fenster, –Die Attribute geben zusätzliche Informationen über das Ereignis, z.B. welcher Button gedrückt wurde. 19

20 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Listener Mehrere Listener können sich bei einer Ereignis-Quelle (event source) registrieren und werden von diesem Zeitpunkt an über Ereignisse eines bestimmten Typs informiert. Programmieren eines Listeners: –Das Klasse des Empfänger-Objekts (event listener) muss das dem Ereignistypen entsprechende Interface implementieren. Z.B. für ActionEvents das Interface ActionListener. –Die Klasse muss alle Methoden des Interface implementieren. –Der Klient registriert nun das Empfänger-Objekt bei der Ereignis-Quelle. Z.B. mittels addActionListener(Listener) 20 event source event object event listener

21 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Ereignisse import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.out.println("Change Label Text was clicked"); } //... } 21 Das ist eine verschachtelte Klasse (nested class). Später mehr dazu!

22 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 View-Updates Die durch Komponenten dargestellten Informationen und ihr Aussehen können durch Aufrufen ihrer Methoden verändert werden. JLabel-API (Auszug): 22 void setText(String) String getText() Setzen oder auslesen des dargestellten Texts void setHorizontalAlignment(int) int getHorizontalAlignment() Textausrichtung: LEFT, CENTER oder RIGHT void setVerticalAlignment(int) int getVerticalAlignment() Textausrichtung: TOP, CENTER oder BOTTOM

23 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Ereignisse import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText( "You clicked the button! Now [Exit] or [X]" ); } //... } 23

24 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Window-Events Beim Klicken auf den Schließen-Button soll das Programm nun korrekt beendet werden. Registrieren eines WindowListeners Interface WindowListener : 24 void windowActivated(WindowEvent e)Window wurde aktiviert void windowClosed(WindowEvent e)Fenster wurde nach dispose() geschlossen void windowClosing(WindowEvent e)Benutzer hat auf Schließen geklickt void windowDeactivated(WindowEvent e)Fenster wurde deaktiviert void windowDeiconified(WindowEvent e)Fenster wurde de-minimiert void windowIconified(WindowEvent e)Fenster wurde minimiert void windowOpened(WindowEvent e)Fenster wurde gerade geöffnet

25 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Adapter Beim Verwenden von Interfaces müssen immer alle Methoden implementiert werden. Das ist oft unpraktisch, deshalb existieren Adapter. WindowAdapter… –implementiert WindowListener –definiert alle Methoden mit leerem Rumpf und somit ohne Verhalten –ist eine abstrakte Klasse. Der anwendungsspezifische Event-Handler wird nun von WindowAdapter abgeleitet und überschreibt nur die interessanten Methoden. 25

26 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 WindowEvents import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title); // Now, also define that the [X] terminates the program correctly addWindowListener(new MyWindowListener()); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); // Create a new push button that may be used in addition to the [X] JButton button = new JButton("Exit"); // Define that the program should exit if you click the button button.addActionListener(new ExitButtonListener()); pane.add(button); 26

27 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Window Events // Create another button that changes the text of the Label button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText("You clicked the button! Now [Exit] or [X]"); } // Exit the program when the window close button is clicked class MyWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } // Exit the program when the Exit-button is clicked class ExitButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { System.exit(0); } public static void main(String args[]) { GUITest theWindow = new GUITest("My first GUI Application"); theWindow.setSize(WIDTH, HEIGHT); theWindow.setVisible(true); } public static final int WIDTH = 400; public static final int HEIGHT = 300; } 27

28 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Verschachtelte Klassen: Motivation Die GUI Komponenten erwarten als Listener eine Instanz von XYZListener (z.B. ActionListener ) Wie können wir ein passendes Listener Objekt erstellen? Option 1: Frame-Klasse implementiert das Listener Interface direkt Option 2: Externe Klasse implementiert das Listener Interface 28

29 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Option 1: Frame-Klasse implementiert das Listener Interface direkt import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame implements ActionListener { public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); JLabel label = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(label); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(this); pane.add(button); } public void actionPerformed(ActionEvent event) { System.out.println("Change Label Text was clicked"); } //... } 29

30 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Option 1: Frame-Klasse implementiert das Listener Interface direkt Diese Möglichkeit funktioniert zwar, ist aber im Allgemeinen unbefriedigend –Was ist, wenn es mehr als einen Button gibt? Klasse kann nicht zwei actionPerformed Methoden haben! –Es gibt nicht nur Buttons, sondern auch Labels, Menus, … Frame-Klasse implementiert eine Menge an Interfaces, die nichts mit seiner eigentlichen Funktionalität zu tun haben –action-Methoden müssen public sein, obwohl es eigentlich Implementationsdetails sind, die nicht zur Schnittstelle von Frame gehören Im Allgemeinen ist dies eine schlechte Lösung 30

31 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Option 2: Externe Klasse implementiert das Listener Interface import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText( "You clicked the button! Now [Exit] or [X]" ); } 31

32 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Option 2: Externe Klasse implementiert das Listener Interface Hat nicht die konzeptuellen Nachteile von Option 1 –z.B. kein Problem, unterschiedliche Aktionen für unterschiedliche Buttons zu definieren –Das Interface des Frames wird nicht verunstaltet Nachteile dieses Ansatzes –Führt zu sehr vielen Klassen Übersichtlichkeit leidet –Geringere Kohäsion Externe Listener-Klasse wird evtl. nur an genau einer Stelle benutzt –Aufwändig und lästig, für jeden Listener eine eigene Klasse anzulegen –Zugriff auf Instanzvariablen/Methoden/lokale Variablen der Frame Klasse aufwändig Alles muss explizit im Konstruktor übergeben werden 32

33 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Option 2: Externe Klasse implementiert das Listener Interface import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener( infoLabel )); pane.add(button); } class ChangeButtonListener implements ActionListener { private JLabel infoLabel; public ChangeButtonListener(JLabel l) { infoLabel = l; } public void actionPerformed(ActionEvent event) { infoLabel.setText( "You clicked the button! Now [Exit] or [X]" ); } 33

34 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Verschachtelte Klassen Beide Möglichkeiten (Option 1 + Option 2) sind nicht zufriedenstellend Dies war die Hauptmotivation für Sun, mit Java 1.1 die verschachtelten Klassen (nested classes) einzuführen Verschachtelte Klassen sind Klassen innerhalb von Klassen –Werden deklariert wie ganz normale Klassen, außer das sie innerhalb anderer Klassen stehen –Einige Zugriffsregeln sind anders –Verschachtelte Klassen haben Zugriff auf Instanzvariablen/Methoden der äußeren Klasse 34

35 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Verschachtelte Klassen import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { private JLabel infoLabel; public GUITest(String title) { super(title); Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ChangeButtonListener()); pane.add(button); } private class ChangeButtonListener implements ActionListener { public void actionPerformed(ActionEvent event) { infoLabel.setText( "You clicked the button! Now [Exit] or [X]" ); } //... } 35 - Nested Class kann private sein - Klasse nur innerhalb der umschließenden Klasse sichtbar - hat Zugriff auf private Instanzvariable der umschließenden Klasse

36 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Verschachtelte Klassen Jede verschachtelte Klasse benötigt bei der Instanziierung eine Referenz auf eine Instanz der umschließenden Klasse –Bei Instanziierung innerhalb der umschließenden Klasse wird diese Referenz implizit übergeben –Außerhalb einer umschließenden Klasse als enclInstance.new MyInnerClass() –Der Typ einer nested Class N innerhalb C ist C.N Innerhalb von C reicht die Typdeklaration N (implizites Scoping) –Daumenregel: Wenn der Name einer nested class außerhalb der umschließenden Klasse benötigt wird, hat man etwas falsch gemacht. Verschachtelte Klassen können auch als static deklariert werden –Semantik analog zu static method: Kein Zugriff auf Instanzvariablen der äußeren Klasse, sondern nur auf static Methoden/Variablen 36

37 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Anonyme verschachtelte Klassen import java.awt.Container; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class GUITest extends JFrame { public GUITest(String title) { super(title); final JLabel infoLabel; // now a local variable Container pane = getContentPane(); pane.setLayout(new GridLayout(3, 1)); infoLabel = new JLabel( "Press the [Exit] or [X] in the top right corner to exit"); pane.add(infoLabel); pane.add(new JButton("Exit")); // Create another button that changes the text of the Label JButton button = new JButton("Change Label Text"); // Now, define what should happen if the button is pressed button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { infoLabel.setText( "You clicked the button! Now [Exit] or [X]" ); } }); pane.add(button); } 37

38 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Anonyme verschachtelte Klassen Man kann innerhalb von Methoden anonyme Klassen anlegen –Diese haben keinen Namen –Sie werden nur über Supertypen angesprochen –Syntax: new SuperClassName(args) { … } oder new InterfaceName() { … } –Erzeugt implizit eine Subklasse der angegebenen Superklasse bzw. eine Klasse, die das angegebene Interface implementiert –Gleichzeitig wird eine Instanz der anonymen Klasse erzeugt –Diese Klasse kann über den angegebenen Superklassen/Interface Namen benutzt werden –Sogar lokale Variablen der Methode können in der Implementierung verwendet werden, sofern sie als final deklariert sind 38

39 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Anonyme verschachtelte Klassen Vorteil gegenüber normalen verschachtelten Klassen –Wenn die Klasse nur an einem einzigen Ort benötigt wird, wird kein Name verschwendet –Definition der Klasse on the fly – dort wo sie benötigt wird –Einfacher Zugriff auf lokale Variablen / Methodenparameter Anonyme Klassen kommen dem lambda aus Scheme recht nahe –Mit lambda können in Scheme Prozeduren on the fly definiert werden 39

40 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Kompilierung von verschachtelten Klassen Wenn eine verschachtelte Klasse kompiliert wird, bekommt man für jede verschachtelte Klasse ein eigenes.class file mit dem NamenOuterClass$InnerClass.class Wenn eine anonyme Klasse kompiliert wird, heißt das File OuterClass$n.class, wobei n eine ganze Zahl ist Intern (auf JVM Ebene) gibt es keine verschachtelten Klassen Der Compiler transformiert intern den Code: –Für jede verschachtelte Klasse wird eine Top-Level Klasse angelegt, die alle benötigten Argumente im Konstruktor übergeben bekommt 40

41 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 GUI und Software Design GUIs können sehr aufwändig und kompliziert sein Die eigentliche Anwendung ebenfalls Wie strukturiert man eine Anwendung mit komplexer GUI? Regel Nr.1: 41 Trennen Sie die Anwendungslogik von der Präsentationslogik

42 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 GUI Antipatterns Sie machen etwas falsch, wenn… –Sie in ihrer GUI-Klasse auf eine Datenbank zugreifen –Ihre GUI-Klasse mehr als 50 KB groß ist –in der GUI-Klasse Geschäftsprozesse implementiert werden –Ihre Anwendungsdaten in GUI-Klassen gespeichert sind –…–… Besser: Schichtenarchitektur –z.B. sog. Model-View-Controller Architektur trennt Daten/Anwendungslogik von Interaktion mit Benutzer Daten/Anwendungslogik hängt nicht von GUI ab einfach, mehrere Views zu unterstützen Austausch von Views einfach 42

43 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Model-View-Controller 43 View Model controller updates Controller Hinweis auf Änderung Zugriff Aktualisieren Behandelt Nutzer- eingaben Anzeige Anwendungsdaten und Verhalten ABC Event senden

44 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 MVC – Das Modell Das Modell enthält die Daten Hat Methoden, um auf Daten zuzugreifen und sie zu ändern Benachrichtigt Listener/Observer, wenn sich die Daten ändern Kann (Teile) der Geschäftsprozesse implementieren 44

45 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 MVC – Der Controller Verarbeitet die Eingaben des Benutzers –zum Beispiel Validierung, Interpretation jeglicher Art, … Häufig zuständig für die Benutzerführung der GUI Kommuniziert diese Eingaben zum Modell Kann präsentationsnahe Teile der Anwendungslogik enthalten –z.B. Interaktionsfluss mit dem Benutzer –scharfe Trennung vom Modell schwierig Kann (muss aber nicht) spezifisch für eine feste GUI sein –Controller hat oder hat nicht eine Instanzvariable die auf die GUI zeigt evtl. entkoppelt über Interface –Bessere Wiederverwendbarkeit im letzteren Fall Schichtenstruktur 45

46 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 MVC – Die View Die View stellt eine visuelle Repräsentation des Modells dar Es kann beliebig viele Views auf dieselben Daten geben –z.B. Mehrere Instanzen derselben View –Aber auch völlig unterschiedliche Views –Zum Beispiel können die Finanzen einer Firma gleichzeitig als Tabelle und als Graph dargestellt werden Registriert sich beim Modell als Listener, zeichnet sich neu, wenn Modell sich ändert. 46

47 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Internationalization (I18N) Internationalisierung: Bereitstellung von Inhalten in mehreren Sprachen Problematisch für GUIs: was muss sich ändern? Beispiel - Menüeintrag: –Text –[optionales] Icon –Kürzel (hier: ALT+G) –Tool tip (Generate…) Die Englische Fassung: 47

48 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Internationalization (I18N) Java bietet Basiselemente für Internationalization Die GUI-Anpassung muss aber vom Programmierer erfolgen Alternative: Nutzung des translator Package –Siehe die Beispiele auf den folgenden Folien Grundlegender Ansatz: –Alle sprachspezifischen Elemente kommen in eine Datei Eine Datei pro unterstützter Sprache –Die Zeilen der Datei sind im Format key=Wert key: ein String, der das Element beschreibt Wert: der auszugebende Wert für den key –Anstelle echter Texte wird im Code nur der key genutzt 48

49 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Sprachressourcen Alle Ressourcen kommen in die sprachspezifische Datei Diese Dateien haben alle den gleichen Basisnamen –Zum Beispiel msg Die Dateierweiterung hat das Format land_SPRACHE –Deutsche Ressourcen stehen also in msg.de_DE –Die US-Englische Fassung steht in msg.en_US –…–… Beispiel für einen Inhalt: 49 hi=Hello! query=How are you today? hi=Hallo! query=Wie geht es Dir? msg.en_USmsg.de_DE

50 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 translator Package: Translator Ziel: Inhaltsübersetzung für eine Zielsprache Nutzt java.util.Locale für die Sprachbestimmung –Vordefinierte Locales: Locale.GERMANY, Locale.US, … –Die Zielausgabe hängt ab von bis zu drei Attributen: Sprache: de, en, es, … Land: de, us, uk, … Variante: spezifischer Code für Browser etc., z.B. WIN Anlegen einer neuen Instanz von Translator –Parameter: Basisname der Ressourcen und Ziel-Locale: Translator myTrans = new Translator(msg, Locale.GERMANY); 50

51 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 translator Package: Translator Übersetzen einer Nachricht über String myTrans.translateMessage(key) Beispiel: –myTrans.translateMessage("hi") Hallo! Manchmal muss die Ausgabe parametrisiert werden –Wie begrüßt man eine Person? Hallo, Herr Schmidt! 51

52 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Übersetzen parametrisierter Texte Das Package unterstützt Parameter in {}: –Angenommen, wir haben diese Definition in unserer Datei: personalized=Hallo, {0}! –Nun können wir einen Parameter übergeben…: myTrans.translateMessage("personalized", "Herr Schmidt"); Hallo, Herr Schmidt! Parameter werden als Zahl ab 0 in {} gesetzt Wenn mehr als ein Parameter erforderlich ist, … –kommen diese in ein Array: translateMessage(key, Object[]) –übergibt man Sie als Strings: translateMessage(key, String…) 52

53 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Internationalisierte GUI-Anwendung Wir werden nun eine kleine GUI-Anwendung bauen: –Ein JFrame dient als Hauptfenster –Mit einem JMenuBar Mit einem Datei-Menü –Das hat einen Exit-Eintrag –Zwei umrahmte JPanel: Eines mit einem JLabel und einem JButton Das zweite hat nur einen Beenden JButton mit Icon Jeder Klick auf den Button erhöht einen Zähler Verlässt man die Anwendung über den Beenden-Button, wird die Anzahl Klicks angezeigt Keine Sorge, das ist einfacher als es wirkt… 53

54 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 I18N GUI Demo – Code I import translator.TranslatableGUIElement; // for GUI elements import translator.Translator; // for I18N of texts etc. // Swing & Event imports skipped – use Eclipse auto-completion! public class I18NDemo { public int nrTimes = 0; // how often was the button clicked? /** * create the I18NDemo instance targetLocale the Locale used for the output */ public I18NDemo(Locale targetLocale) { // create the translator (resource file; target locale) Translator translator = new Translator("guiI18N", targetLocale); buildGUI(translator); // create the GUI } 54

55 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 I18N GUI Demo – Code II /** * builds the GUI elements with full I18N support translator the Translator instance to be used */ public void buildGUI(final Translator translator) { // retrieve the GUI element builder TranslatableGUIElement guiBuilder = translator.getGenerator(); // create the window itself with an I18N title JFrame aFrame = guiBuilder.generateJFrame("guiDemo"); aFrame.getContentPane().setLayout(new BorderLayout()); // create a JMenuBar JMenuBar menuBar = new JMenuBar(); 55

56 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 I18N GUI Demo – Code III // generate the JMenu for this JMenu menu = guiBuilder.generateJMenu("fileMenu"); // generate a menu item with (key, useIconIfExists) JMenuItem exitItem = guiBuilder.generateJMenuItem("exitItem", true); exitItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); // exit }}); // add the item to the JMenu menu.add(exitItem); // add the menu to the menu bar and add this to the JFrame menuBar.add(menu); aFrame.setJMenuBar(menuBar); 56

57 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 I18N GUI Demo – Code IV JPanel infoPanel = guiBuilder.generateBorderedJPanel("infoPanel"); aFrame.getContentPane().add(infoPanel, BorderLayout.CENTER); // translatable JLabel JLabel label = guiBuilder.generateJLabel("clickMe"); infoPanel.add(label); // add the info button AbstractButton info = guiBuilder.generateJButton("clickButton"); info.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.err.println(translator.translateMessage("pressedN", String.valueOf(++nrTimes))); // show nr of button press } }); infoPanel.add(info); // add the info panel 57

58 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 I18N GUI Demo – Code V JPanel exitPanel = guiBuilder.generateBorderedJPanel("exitPanel"); aFrame.getContentPane().add(exitPanel, BorderLayout.SOUTH); AbstractButton exit = guiBuilder.generateJButton("exitButton"); // exit button exit.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { System.err.println(translator.translateMessage("bye", String.valueOf(nrTimes)); System.exit(0); // show good bye & # of pressed, exit }); exitPanel.add(exit); aFrame.pack(); aFrame.setVisible(true); } public static void main(String[] args) { I18NDemo demo = new I18NDemo(Locale.GERMANY); } 58

59 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Ergebnis der GUI-Demo Hier ist das Ausgabefenster: 59 JFrame JMenuBar mit JMenu Datei, Kürzel D JMenuItem Verlassen mit Icon, Kürzel V, und Tooltip JLabel JButton, Kürzel Z Tooltip des Menüeintrags JButton, Kürzel B, mit Icon Umrahmtes JPanel

60 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Ergebnis der GUI-Demo Und hier die englische Fassung: 60 JFrame JMenuBar mit JMenu File, Kürzel F JMenuItem Exit mit Icon, Kürzel X, und Tooltip JLabel JButton, Kürzel I Tooltip des Menüeintrags JButton, Kürzel X, mit Icon Umrahmtes JPanel Um dieses Fenster zu erhalten, ändert man eine Zeile: I18NDemo demo = new I18NDemo(Locale.US);

61 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Abschließende Kommentare Sie haben es vielleicht nicht bemerkt… –Beide buttons, das Menü und der Menüeintrag haben ein Kürzel (mnemonic) –Alle GUI-Elemente haben einen tool tip text Aber die Texte etc. sind im Code nicht angegeben! –Weil sie alle aus der Ressource-Datei stammen! –Diese wird auf den folgenden Folien gezeigt Spielen Sie ein wenig mit der API –Sie finden Sie auf der Webseite mit Zusatzinfos –Der Source code kann dort auch heruntergeladen werden Man kann die Inhalte auch on the fly übersetzen –Einfach aufrufen translator.setTranslatorLocale(newLocale) 61

62 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Englische Ressourcedatei zur GUI Demo hi=Hello! personalized=Hello, {0}! multi=One {0} two {1} three {2} parameters noSuchKeyException=There is no ressource for element {0} exitPanel=Exit Panel exitButton.iconName=quit.gif exitButton.label=Exit exitButton.mnemonic=x exitButton.toolTipText=Click this button to end the demo clickButton.iconName= clickButton.label=Increment counter clickButton.mnemonic=i clickButton.toolTipText=Click here to increment the counter infoPanel=Info Area clickMe=Click here: fileMenu.label=File fileMenu.mnemonic=f fileMenu.toolTipText=Contains the Exit item exitItem.iconName=quit.gif exitItem.label=Exit exitItem.mnemonic=x exitItem.toolTipText=Exits the application pressedTimes=The increment button was pressed {0} times. bye=Good bye - and thank you for pressing the button {0} times. guiDemo=Internationalization Demo 62

63 Dr. G. Rößling Prof. Dr. M. Mühlhäuser RBG / Telekooperation © Grundlagen der Informatik I: T21 Deutsche Ressourcedatei zur GUI Demo hi=Hallo! personalized=Hallo, {0}! multi=Eins {0} zwei {1} drei {2} Parameter noSuchKeyException=Es gibt keine Ressource f\u00fcr Eintrag {0} exitPanel=Beenden exitButton.iconName=quit.gif exitButton.label=Beenden exitButton.mnemonic=b exitButton.toolTipText=Dr\u00fccken Sie diesen Knopf zum Beenden clickButton.iconName= clickButton.label=Z\u00e4hler inkrementieren clickButton.mnemonic=z clickButton.toolTipText=Klicken Sie hier, um den Z\u00fchler zu inkrementieren infoPanel=Info-Bereich clickMe=Bitte hier klicken: fileMenu.label=Datei fileMenu.mnemonic=d fileMenu.toolTipText=Enth\u0fe4lt nur den Eintrag 'Verlassen' exitItem.iconName=quit.gif exitItem.label=Verlassen exitItem.mnemonic=v exitItem.toolTipText=Beendet die Anwendung pressedTimes=Der Inkrementieren-Knopf wurde {0} Mal gedr\u00fcckt. bye=Auf Wiedersehen - und Danke, dass Sie den Knopf {0} Mal gedr\u00fcckt haben. guiDemo=Demo zur Internationalisierung 63


Herunterladen ppt "Telecooperation/RBG Technische Universität Darmstadt Copyrighted material; for TUD student use only Grundlagen der Informatik 1 Thema 21: GUI und verschachtelte."

Ähnliche Präsentationen


Google-Anzeigen