Vorlesung „Programmieren“ GUIs mit Java Prof. Dr. Stefan Fischer Institut für Telematik, Universität zu Lübeck https://www.itm.uni-luebeck.de/people/fischer Bisher... 2 Apple Lisa Office System 3.1 3 Graphical User Interface (GUI) • Grafische Benutzeroberflächen sind oft unentbehrlich – Intuitiv bedienbare Programme – Konsolenprogramme nur für „Hacker“ • Java hat umfangreiche Unterstützung zur GUIProgrammierung – „Normale“ Programme – Programme, die im Browser laufen, sog. Applets • Vorteil von Java-GUIs – Plattformunabhängigkeit (write once, run anywhere) GUI Programmierung in Java • Es gibt zwei integrierte APIs für GUIs in Java • Abstract Window Toolkit (AWT) – – – – Verwendet Standardbibliotheken des Betriebssystems Sehen aus wie native Anwendungen (original „Look-and-Feel“) Gute Performance Nachteil: Geringer Funktionsumfang (kleinster gemeinsamer Nenner) • Swing – – – – Sehr großer Funktionsumfang Vollständig in Java implementiert, keine nativen Komponenten „Look-and-Feel“ kann konfiguriert werden Nachteile • Performance in einigen Bereichen eingeschränkt • Sieht immer wie eine Java-Anwendung aus Akzeptanz AWT (Windows) vs. Swing 6 Einführung in Swing • GUI besteht aus sichtbaren und unsichtbaren Elementen, z.B.: – – – – – Fenster Menüs Textlabels Buttons Panels • Dies alles sind Java Objekte (d.h. Instanzen) – Zugehörigen Klassen im package javax.swing.* Einfaches Fenster (manuell vergrößert) 8 JLabel 9 Gängige Swing-Komponenten (Java Look and Feel) JButton JCheckBox JComboBox JList JSlider JRadioButton JSpinner JMenu JTextField JPasswordField 5-5-10 Gängige Swing-Komponenten (Windows Look and Feel) JButton JCheckBox JComboBox JList JSlider JRadioButton JMenu JTextField JSpinner JPasswordField 5-5-11 Top-Level-Container • Swing hat drei Top-Level-Container: – JFrame („normales“ Programmfenster) – JApplet (Programmfenster im Browser) – JDialog (Dialog-Box, z.B. für Fehlermeldungen) • Beispiel: JFrame 5-5-12 „Anatomie“ eines JFrames 5-5-13 Layout • Layout bestimmt Anordnung von GUI-Komponenten – Wie werden zwei Buttons angeordnet in einem JFrame? – Programmfenster können vergrößert und verkleinert werden • Daher ist eine absolute Positionierung ungünstig • Wie kommt man zu einem sinnvollen Layout? – Lösung: Layout-Manager • Im Folgenden: die wichtigsten Layout-Manager 5-5-14 FlowLayout • Komponenten werden in einer Zeile angeordnet – Reicht die Breite nicht, beginnt eine neue Zeile 5-5-15 FlowLayout 16 BorderLayout • Fläche in fünf Bereiche aufgeteilt – North, South, East, West, Center – Center ist der priorisierte Bereich 5-5-17 BorderLayout 18 BoxLayout • Komponenten werden in einer Zeile oder Spalte angeordnet – Komponenten-Größe wird berücksichtigt – Komponenten können aneinander ausgerichtet werden • Linksbündig, Rechtsbündig, Zentriert 5-5-19 BoxLayout 20 GridLayout • Komponenten werden in einer Matrix angeordnet – Zeilen- und Spaltenzahl variabel – Zellen haben einheitliche Größe 5-5-21 GridLayout 0 Zeilen 2 Zeilen beliebig viele feste Anzahl 22 GridBagLayout • Ordnet Komponenten in einem Raster an – – – – Höhen und Breite von Zeilen/Spalten kann unterschiedlich sein Komponenten können sich über mehrere Zeilen und Spalten erstrecken Vergrößern/Verkleinern individuell durch „Gewichte“ einstellbar Sehr flexibel einsetzbar 5-5-23 GridBagLayout 24 25 JPanel • Anordnung (und Gruppierung) von Komponenten – Normalerweise reicht nicht ein Layout-Typ – Oft wird eine Kombination verschiedener Layouts benötigt • Sinnvoll: Unterteilung der „Content Pane“ – Auswahl eines Top-Level Layouts – Innerhalb der einzelnen Bereiche Verwendung anderer LayoutManager • Hilfreich: Klasse JPanel – Leere Fläche auf der Komponenten angeordnet werden – Jede Instanz hat einen eigenen Layout-Manager 5-5-26 JPanel (Beispiel) JFrame mit BorderLayout (je 1 JPanel South/Center) JPanel mit GridLayout und fünf JButtons JPanel mit GridLayout und drei JButtons JPanel (Beispiel) – Source Code 28 Layout mit GUI-Builder • Anordnen der Komponenten „per Hand“ vergleichsweise mühselig – Daher: Programme zum Gestalten von GUIs per „Drag and Drop“ • Vorteile – Geringerer Programmieraufwand – Hohe Geschwindigkeit zum ersten Entwurf • Nachteile – Zusammengeklickte GUIs sind oft nicht optimal – Verhalten unter schwierigen Bedingungen (z.B. sehr kleine oder große Fenster) nicht immer gut • Zeit zum manuellen Aufbau einer GUI ist oft gut investiert 5-5-29 GUIs und der „Event Dispatching Thread“ (EDT) • GUI-Programme laufen nicht sequenziell ab – Aktionen werden durch Benutzeraktionen getrieben – Beispiele: Mausklicks, Tastendrücke, etc. Event-basierter Programmablauf • Event-Verarbeitung im EDT – Ein Thread ist ein „Ausführungspfad“, der parallel zu anderen Threads abläuft, insbesondere dem main-Thread • Modifikationen der GUI nur im EDT – „Sprung“ in den EDT über javax.swing.SwingUtilities.invokeLater(…) oder javax.swing.SwingUtilities.invokeAndWait(...) 5-5-30 Events erzeugen und auswerten • Wie kann man nun Events erzeugen? – Passiert automatisch in den Komponenten – z.B. wenn ein JButton durch den Benutzer betätigt wird • Wie kann man diese auswerten? – Ein Event ist ein Java-Objekt – Komponente „schickt“ das Event an alle Instanzen, die sich als Listener registriert haben registriert sich Komponente (besitzt eine Liste aller registrierten Listener) schickt Events 1. Listener registriert sich schickt Events 2. Listener 5-5-31 Events fangen mit Event-Listenern 32 Version 2: alles in einer Klasse Weitere Events • Bisher: ActionEvents – Häufig bei JButton- und JRadioButton-Objekten • Weitere Events: – ItemEvent, – MouseEvent, – ChangeEvent, z.B. für JCheckBox-Objekte z.B. um Position der Maus abzufragen z.B. um Zustandsänderungen bei Jslider • Anwendungsprinzip folgt immer dem gleichen Muster – Details zu den relevanten Event-Typen sowie zahlreiche Anwendungsbeispiele verfügbar unter: http://download.oracle.com/javase/tutorial/uiswing/components/componentlist.html 5-5-34 Event-Interfaces und Event-Adapter • • • Empfangen von Events – Klasse implementiert das entsprechende Interface – Bei ActionListener einfach nur eine Methode Aufwändiger ist z.B. die Implementierung von MouseListener: – void mouseClicked(MouseEvent e) – void mouseEntered(MouseEvent e) – void mouseExited(MouseEvent e) – void mousePressed(MouseEvent e) – void mouseReleased(MouseEvent e) Aber: Was wenn nur Mausklicks interessieren? – Es müssten alle 5 Methoden implementiert werden – Nur eine (mouseClicked) enthält Programmcode – Der Rest ist leer: Aufwändig, schlechter Stil, schlecht lesbar Überflüssig 36 Event-Interfaces und Event-Adapter • Sog. Adapter helfen, Schreibarbeit zu sparen – Fertige (abstrakte) Klassen, die alle Interface-Methoden leer bereitstellen • Vorteil: Nur benötigte Methoden des Adapters werden überschrieben • Häufige Anwendung: – Es wird keine neue Klassendatei erstellt – Stattdessen: sog. „anonymous inner classes“ 5-5-37 Event-Interfaces und Event-Adapter MouseAdapter als anonyme, innere Klasse 39 Erscheinungsbild von GUI-Komponenten verändern • Swing stellt bereits viele Standardkomponenten bereit – Mitunter benötigt man spezialisierte Komponenten – GUI Komponenten können selbst „gezeichnet“ werden • Beispiel – Anzeige und Auswertung von Messwerten – Interaktive Stadtpläne, Notensatz • „Zeichnen“ von GUI-Komponenten in der Methode paint – void paint(Graphics g) – Graphics-Objekt g repräsentiert dabei die „Zeichenfläche“ – Erbt man von einer GUI-Komponente und überschreibt diese Methode, so verändert sich das Erscheinungsbild der Instanz der Unterklasse 5-5-40 Erscheinungsbild von GUI-Komponenten verändern 41 Erscheinungsbild von GUI-Komponenten verändern • Weitere Infos – Swing • http://download.oracle.com/javase/tutorial/uiswing/ – AWT • http://java.sun.com/developer/onlineTraining/awt/cont ents.html – SWT • http://www.eclipse.org/swt/ 43