Programmiertechnik GUI Programmierung mit Java Swing Prof. Dr. Oliver Haase Software Engineering und Verteilte Systeme Raum F012 [email protected] Tel: 07531/206-720 Oliver Haase Hochschule Konstanz 1 Java AWT und Swing Java enthält zwei Pakete zur Programmierung graphischer Oberflächen. java.awt: Das Abstract Window Toolkit ist das ältere, weniger komfortable Paket. javax.swing: Swing ist das neuere, komfortablere Paket. Swing baut auf dem AWT auf. In dieser Vorlesung Swing. Zum Auftakt ein einzelnes Swing-Fenster mit Nachricht… Merke: Auch der beste GUI-Designer hat mal klein angefangen! Oliver Haase Hochschule Konstanz 2 Ein erster Gehversuch… Und so wird’s gemacht: import javax.swing.*; Swing-Paket importieren Top-Level Container erzeugen public class HelloWorldSwing { public static void main(String[] args) { Programm JFrame frame = new JFrame("HelloWorldSwing"); beenden, frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE); wenn JLabel label = new JLabel("Hello world, " Fenster + "take a look at my first GUI."); zu frame.add(label); Label erzeugen frame.pack(); und in Frame Größe frame.setVisible(true); einfügen berechnen } } anzeigen Oliver Haase Hochschule Konstanz 3 Top-Level Container Jede Swing-Applikation muss als alles umschließende Fenster einen sogenannten Top-Level Container erzeugen. Es gibt drei Arten von Top-Level Containern: JFrame: Hauptfenster, das standardmäßig einen Rahmen mit Titel sowie Funktionsfeldern zum Minimieren, Maximieren und Schließen enthält – und, nicht zu vergessen, eine JavaKaffeetasse . JApplet: Analog für Swing-basierte Java Applets. Oliver Haase Hochschule Konstanz 4 Top-Level Container JDialog : Fenster für einfache Dialoge mit dem Benutzer, etwa kurze Meldungen, die quittiert werden müssen, oder Auswahllisten. Sind i.d.R. abhängig von einem anderen TopLevel-Container. Beispiel: Oliver Haase Hochschule Konstanz 5 Top-Level Container Ein Top-Level Container enthält graphische Komponenten (abstrakte Klasse JComponent). Eine Komponente kann sein: wieder ein Container (kein Top-Level Container!), oder ein graphisches Element wie z.B. ein Button ein Label ein Bild eine Auswahlliste Oliver Haase Hochschule Konstanz 6 GUI-Klassenmodell Top-Level Container Komponente Container Oliver Haase graphisches Element Hochschule Konstanz 7 Innere Container Dienen dazu, die graphische Benutzeroberfläche zu strukturieren. Es gibt verschiedene Arten innerer Container, z.B. Panels: Ein Panel ist eine logische Gruppierung von Komponenten. Panels können durch eine eigene Hintergrundfarbe und/oder einen Rahmen vom umschließenden Container abgesetzt werden. Top-Level Container (JFrame) enthält rotes Panel enthält lila Panels Oliver Haase Hochschule Konstanz 8 Innere Container Scrollbare Container (scroll panes): Mehrfachcontainer mit Reitern (tabbed panes): Oliver Haase Hochschule Konstanz 9 Interaktive GUI Interaktive GUI mit Button und Label. Interaktiv heißt, dass der Benutzer durch seine Aktionen (Klicken des Buttons) Änderungen an der GUI (am Label) durchführen kann. Interaktion ist möglich durch ein Event-Listener-Modell. Oliver Haase Hochschule Konstanz 10 Event-Listener-Modell In einem Programm mit graphischer Oberfläche liegt die Ausführungskontrolle beim Fenstersystem. Wenn der Benutzer eine Aktion tätigt (Mausklick, Tastendruck, …), wird ein Event ausgelöst, das vom Fenstersystem an die betreffende Komponente (z.B. an den Button, auf den geklickt wurde) weitergeleitet wird. Daraufhin wird der Code ausgeführt, der mit der Komponente und dem Event verknüpft ist. Dazu wird der gewünschte Code als Event-Listener bei der graphischen Komponente angemeldet. Oliver Haase Hochschule Konstanz 11 Event-Listener-Modell graphische Komponente (z.B. Button) 4. aufrufen 1. registrieren Event-Listener 3. Event an passende Komponente schicken Fenstersystem (JavaLaufzeitsystem) 2. Aktion (z.B. Mausklick) aber: wie werden 1. und 4. durchgeführt? Oliver Haase Hochschule Konstanz 12 Schritt 4: Event-Listener aufrufen Frage: Wie wird der Event-Listener aufgerufen? Anders formuliert: Welche Methode am Event-Listener-Objekt soll aufgerufen werden, und welche Parameter bekommt diese Methode übergeben? Beachte: Funktioniert nur, wenn jeder Event-Listener eine bestimmte Methode implementiert, deren Signatur die graphische Komponente kennt. Wie kann das garantiert werden? Antwort: Über eine geeignete Schnittstelle, die jeder Event-Listener implementieren muss! Oliver Haase Hochschule Konstanz 13 ActionListener Beispiel: Jeder Event-Listener für einen Button muss die Schnittstelle java.awt.event.ActionListener implementieren. Das Interface ActionListener definiert nur eine Methode, nämlich void actionPerformed(ActionEvent e). Das Eingabeobjekt e vom Typ ActionEvent gibt Auskunft über die Art des Events, wie z.B. ob die SHIFT- oder CTRL-Taste gedrückt war zum Zeitpunkt des Events. Diese Information kann im EventHandler-Code verwendet werden. Der eigentliche Event-Handler-Code muss in die Methode actionPerformed gesteckt werden. Oliver Haase Hochschule Konstanz 14 Schritt 1: Event-Listener registrieren Durch die Registrierung wird das Event-Listener-Objekt der graphischen Komponente bekanntgemacht; durch geeignete Typisierung sichergestellt, dass der EventListener die erforderliche Schnittstelle implementiert. Der 2. Punkt wird erreicht, indem die Methode zur Registrierung eines Event-Listeners (für Buttons) ein Objekt vom Typ ActionListener erwartet. D.h. der Event-Listener muss Instanz einer Klasse sein, die die Schnittstelle ActionListener implementiert. Oliver Haase Hochschule Konstanz 15 Schritt 0: Event-Listener erstellen Event-Listener muss java.awt.event.ActionListener implementieren; void actionPerformed(ActionEvent e) definieren import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JLabel; public class MyActionListener implements ActionListener { private int numClicks; private JLabel label; public MyActionListener(JLabel label) { this.label = label; } public void actionPerformed(ActionEvent e) { numClicks++; label.setText(SwingApplication.LABEL_PREFIX + numClicks); } } Oliver Haase Hochschule Konstanz 16 Beispiel-Programm Hauptklasse: import javax.swing.*; import java.awt.*; public class SwingApplication { public static final String LABEL_PREFIX = "Number of button clicks: "; public static Component createComponents() { JLabel label = new JLabel(LABEL_PREFIX + "0 "); JButton button = new JButton("I'm a Swing button!"); button.addActionListener(new MyActionListener(label)); JPanel pane = new JPanel(new GridLayout(0, 1)); pane.add(button); pane.add(label); pane.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30)); return pane; } Oliver Haase Hochschule Konstanz 17 Beispiel-Programm public static void main(String[] args) { // Create and set up the window. JFrame frame = new JFrame("SwingApplication"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Component contents = createComponents(); frame.add(contents, BorderLayout.CENTER); // Display the window. frame.pack(); frame.setVisible(true); } } Oliver Haase Hochschule Konstanz 18 JOptionPane Mit Hilfe der Klasse JOptionPane können simple Dialog-Fenster (JDialog) sehr einfach erzeugt werden. Die wichtigsten Kategorien sind: Message Dialog: dient dazu, dem Benutzer eine Nachricht anzuzeigen. Confirm Dialog: bittet den Benutzer um eine Bestätigung, wie z.B. Yes, No oder Cancel. Input Dialog: liest eine Auswahl oder eine freie Eingabe des Benutzers ein. Oliver Haase Hochschule Konstanz 19 Message Dialog einfachste Form: JOptionPane.showMessageDialog(null, "hello world!"); Erster Parameter gibt das Elternfenster an, von dem der Dialog abhängt. Oliver Haase Hochschule Konstanz 20 Confirm Dialog einfachste Form: int choice = JOptionPane.showConfirmDialog(null, "Do you want to say hello to the world?"); Erster Parameter gibt wiederum das Elternfenster an, von dem der Dialog abhängt. Rückgabewert gibt die Auswahl des Benutzers an (Index des geklickten Buttons): Oliver Haase Hochschule Konstanz 21 Input Dialog einfachste Form: String input = JOptionPane.showInputDialog(null, "What do you want to say to the world?"); Erster Parameter gibt wiederum das Elternfenster an, von dem der Dialog abhängt. Gibt den eingegebenen Text zurück (null falls mit Abbrechen verlassen) Oliver Haase Hochschule Konstanz 22 JOptionPane - Bemerkungen Es wurden nur die einfachsten Varianten gezeigt. Alle Kategorien können den Bedürfnissen angepasst werden. Beispiel: Für ein Input Dialog kann eine Auswahlliste angegebenen werden. Beispiel: Die möglichen Buttons eines Confirm Dialogs können selbst bestimmt werden. Oliver Haase Hochschule Konstanz 23 Schlussbemerkung… Oliver Haase Hochschule Konstanz 24