Universität Dortmund, Fachbereich Informatik Peter Bollweg, OH16 E08, bollweg@ls7.cs.uni-dortmund.de, 6328 Constantin Timm, OH16 E06, timm@ls12.cs.uni-dortmund.de, 6144 Christian Asche Dortmund, 19. Oktober 2006 Mensch-Maschine-Interaktion Übungsblatt Nr. 1 Übungsgruppen: Nr. Termin Abnahme der praktischen Aufgaben 1 Mo 10.15 11.45 GBV/014+015 2 Di 10.15 11.45 GBV/014+015 3 Di 14.15 15.45 GBV/014+015 4 Mi 12.15 13.45 GBV/014+015 5 Do 14.15 15.45 GBV/014+015 6 Fr 10.15 11.45 GBV/014+015 Die Bearbeitung der Aufgaben kann in Gruppen bis zu 3 Personen erfolgen. Allerdings ist eine aktive Teilnahme an den Übungen Voraussetzung zur Erlangung eines Scheins, d.h. jeder Teilnehmer sollte die abgegebenen Lösungen auch erklären können. Die Abnahme des Übungsblatts 1 erfolgt in der Woche vom 06.11. bis 10.11.2006 in den Rechnerpools es ist nichts Schriftliches abzugeben. Für dieses Übungsblatt sollten Sie Zugriff auf die Dokumentation der Java API haben. Einen entsprechenden Link finden Sie unter http://ls7- www/students/lectures/doc_mmi0607/uebungen.shtml. Falls sie die Aufgaben zu Hause bearbeiten sollten: unter o.a. URL befindet sich ebenfalls ein Download-Bereich für jedes Übungsblatt. Laden Sie jeweils die ZIP-Datei herunter und entpacken Sie diese. Die Datei enthält bereits vorgefertigte Klassen, von denen Sie eigene Klassen ableiten bzw. bei denen Sie einzelne Methoden implementieren oder modifizieren sollen, sowie Dokumentation zu den vorgefertigten Klassen. Falls Sie die Aufgaben in den Rechnerpools bearbeiten sollten: die oben genannnten Dateien finden Sie in den Unterverzeichnissen class, doc und orig Ihres Home Verzeichnisses. Aufgabe 1.1 (Einfache Komponenten von Swing) Swing stellt eine Fülle an Komponenten zur Verfügung, die in ein Fenster bzw. in einen Dialog eingebettet werden können. Einige Beispiele sind Labels (JLabel) ein Text, ein Bild oder beides (vgl. Blatt 0) Buttons (JButton) diese können einen Text, ein Bild oder beides darstellen, und werden meistens mit einem ActionListener verbunden Panels (JPanel) dient der Aufnahme anderer Komponenten, wird oft auch zur Ausgabe von Zeichnungen verwendet Check-Boxen (JCheckBox) stellen einen Text dar, den der Benutzer mit einem Häkchen versehen kann; werden manchmal mit einem ItemListener verbunden wenn man nicht an der Änderung sondern nur an dem Ergebnis interessiert ist, setzt man keinen Listener und fragt erst nach Schließen des Dialogs den jeweiligen Status ab
Radio-Buttons (JRadioButton) ähnlich wie Check-Boxen, allerdings kann hierbei jeweils nur ein Häkchen gesetzt werden Auswahlboxen (JComboBox) dienen dazu, mit der Maus eine Alternative aus einer Menge auszuwählen; wenn man an einer etwaigen Veränderung durch den Benutzer unmittelbar interessiert ist, sollte man einen ActionListener setzen Textfelder (JTextField) dienen der Eingabe einer Textzeile; durch Drücken der Return-Taste wird u.a. ein Aktionsereignis ausgelöst Schieberegler (JSlider) dienen der Abfrage eines numerischen Wertes innerhalb eines Intervalls (mit getvalue()); ist man an der Veränderung des Wertes unmittelbar interessiert, d.h. noch während er durch den Benutzer verändert wird, so setzt man einen ChangeListener Karteikarten (JTabbedPane) dienen zur Erstellung eines Registerkartensatzes Komponenten können nicht nur in Fenster, sondern auch in andere Komponenten (JPanel, JTabbed- Pane) mittels add(...) eingefügt werden (vgl. auch Aufg. 1.3). Insbesondere bei Registerkarten fügt man ein Panel ein, das weitere Komponenten enthalten kann, da sonst nur eine einzige Komponente pro Karteikarte möglich wäre. = H J A E 2 = A = > A 6 A N J B A @ * K J J Abbildung 1: Eine Registerkarte mit eingefügten Komponenten. Abbildung 2: Ein Fenster mit Radio- Buttons. a) (1 P-Punkt) Leiten Sie von der Klasse simpleframe diese implementiert bis auf die main- Methode ein einfaches Fenster eine Klasse elementetest ab und fügen Sie in das Fenster einen Karteikartensatz ein (parameterloser Konstruktor). Sie können einzelne Karteikarten über die Methode add(string,component) einfügen, wobei der String den Text angibt, der oben auf der Karteikarte steht. b) (1 P-Punkt) Fügen Sie eine Registerkarte hinzu, die ein Label mit leerem Text und dem Bild ls7logo.gif enthält. c) (1 P-Punkt) Ergänzen Sie eine Karteikarte, die einen Button mit beliebigem Text und dem Bild ls7logo.gif enthält. Wenn der Button gedrückt wird, soll dies mit System.out.println(...) ausgegeben werden.
d) (2 P-Punkte) Fügen Sie eine Karteikarte mit einem Textfeld hinzu. Das Textfeld soll in der Darstellung 12 Zeichen lang sein und ursprünglich keinen Text enthalten. Gibt der Benutzer einen Text ein und schließt dieses durch Drücken der Return-Taste ab, so ist dieser im Label aus Aufgabenteil a) zu setzen. e) (3 P-Punkte) Ergänzen Sie eine Karteikarte mit Schieberegler. Dieser soll die Werte von 0 bis 255 ermöglichen und mit 0 initialisiert sein. Setzen Sie die Vordergrundfarbe auf schwarz und rufen Sie setpaintticks(true), setpaintlabels(true) und setmajortickspacing(51) auf. Hierdurch wird eine beschriftete Skala gezeichnet, deren Beschriftung in 51er Schritten vorgenommen wird. Verbinden Sie den Schieberegler mit einem ChangeListener, der nur eine Methode zum Abfangen von Swing-Ereignissen implementiert public void statechanged(changeevent event) Implementieren Sie den Listener so, dass sich der Grünanteil der Vordergrundfarbe des Schiebereglers gemäß seinem Wert ändert. f) (2 P-Punkte) Erzeugen Sie eine Registerkarte mit einer Check-Box mit Vordergrundfarbe grün, Hintergrundfarbe rot und der Beschriftung invers. Implementieren Sie die Funktionalität der Check-Box so, dass Vorder- und Hintergrundfarbe vertauscht werden, wenn der Benutzer die Check-Box anklickt. g) (1 P-Punkt) Erstellen Sie eine Registerkarte, die eine Auswahlbox mit wenigstens 3 Elementen enthält. Elemente können mittels additem(string) hinzugefügt und mit getselecteditem() kann der selektierte Eintrag erfragt werden. Geben Sie über einen Listener mit System.out.println(...) aus, welcher Eintrag vom Benutzer selektiert wurde. Aufgabe 1.2 (Zeichnen einer Komponente) Wie in Aufg. 1.1 erwähnt, kann man Panels auch zum Zeichnen verwenden. Hierfür leitet man von JPanel eine Klasse ab und überschreibt die Methode paintcomponent(graphics), der ein Graphics- Objekt des AWT übergeben wird. Dieses dient dann zur Ausgabe von einfachen Geometrien wie Rechtecke, Kreise, Linien etc. Hierbei können verschiedene Zustände, z.b. Farben, gesetzt werden, die so lange gültig sind, bis ein neuer Zustand gesetzt wird. Es ist also eine Zustandsmaschine gegeben, die sich den letzten Zustand (Farbe) merkt, und diesen auf alle nachfolgenden Operationen anwendet. Methoden zum Zeichnen beginnen mit draw und ausgefüllte Flächen werden mit fill... gezeichnet. a) (2 P-Punkte) Implementieren Sie die Methode paintcomponent(graphics g) in der Klasse zeichenpanel. Rufen Sie zuerst die Methode der Oberklasse auf. Zeichnen Sie anschließend ein gefülltes rotes Rechteck, eine Grüne Elipse, einen beliebigen schwarzen Text und eine schwarze Linie. b) (1 P-Punkt) Wenn Sie die Fenstergröße ändern, merken Sie, dass ein Teil Ihrer Zeichnung ggf. abgeschnitten wird. Wir werden in dieser Aufgabe Scroll-Balken hinzufügen, um das zu verhindern. Dies wird über eine JScrollPane erledigt. Fügen Sie hierfür in der Klasse paintframe statt panel eine ScrollPane in die ContextPane ein. Die ScrollPane instanziieren Sie zuvor mit panel als Parameter für den Konstruktor. Jetzt muss noch das zeichenpanel bekannt geben, welche Größe es besitzt. Dies geschieht durch Aufruf der Methode public void setpreferredsize(dimension preferredsize)
im Konstruktor der Klasse zeichenpanel. Sie sollten die angegebenen Werte natürlich größer oder gleich der maximalen Ausdehnung Ihrer Zeichnung wählen, da sonst wieder abgeschnitten wird. Werte größer 2 15 können allerdings, auch beim Zeichnen, zu Problemen führen. Aufgabe 1.3 (Layout) Bisher haben wir Komponenten lediglich in andere Komponenten eingefügt, ohne uns um das Aussehen zu kümmern. Komponenten können aber nicht nur eingefügt, sondern auch innerhalb anderer Komponenten angeordnet werden. Hierfür stellt Java verschiedene LayoutManager zur Verfügung. Beispiele sind FlowLayout die Komponenten werden gemäß der Reihenfolge ihres Einfügens aneinandergehängt BorderLayout es werden Himmelsrichtungen (u.a. als Strings North, East, South, West und Center ) vergeben und man gibt beim Einfügen die Richtung an, in die die Komponente geschoben werden soll GridLayout die Komponenten werden auf einem Gitter angeordnet; bei Erzeugung eines GridLayouts wird die Zahl der Zeilen und Spalten angegeben und die Zellen werden durch das Einfügen von Komponenten nacheinander belegt GridBagLayout ein sehr komplexer LayoutManager, der auch kompliziert aufgebaute Dialoge ermöglicht Null-Layout (als Manager wird null übergeben) dieser erlaubt absolute Positionierungen von Komponenten, ist allerdings mit Vorsicht zu genießen, da Komponenten beim Zeichnen unterschlagen werden können (Zusammenspiel von AWT und Swing) Der Vorteil von LayoutManagern ist, dass bis auf das Null-Layout alle Manager die Darstellung der aktuellen Fenstergröße anpassen. LayoutManager sind Instanzen der entsprechenden Klasse und können in einer Komponente (meistens Panels) mit setlayout(layoutmanager) gesetzt werden. a) (1 P-Punkt) Leiten Sie von der abstrakten Klasse layoutframe eine Klasse layouttest ab und implementieren Sie die main-methode zum Darstellen des Fensters. Überschreiben Sie die Methode protected void init_layouts(jtabbedpane tabbedpane) Diese dient der Initialisierung eines Registerkartensatzes zur Darstellung verschiedener Layouts. Fügen Sie tabbedpane ein Panel hinzu, das ein FlowLayout und mehrere Labels hat. Die Labels erhalten Sie über die Methode protected JLabel[] create_labels() in der Klasse layoutframe. b) (1 P-Punkt) Fügen Sie eine Karteikarte mit einem Panel mit GridLayout (3 Zeilen und 4 Spalten) hinzu. Für die Labels rufen Sie erneut create_labels() auf, da sonst seltsame Effekte bei der Positionierung der Labels entstehen könnten.
c) (1 P-Punkt) Ergänzen Sie eine Registerkarte mit Panel mit BorderLayout. Fügen Sie dem Panel die ersten fünf Labels, die Sie durch einen erneuten Aufruf von create_labels() erhalten, in alle Himmelsrichtungen hinzu. Die Anatomie eines Swing-Programms Nach den einführenden Aufgaben lässt sich der Aufbau einer GUI mittels Swing folgendermaßen beschreiben: 1. Die benötigten AWT- und Swing-Bibliotheken importieren. 2. Eine Klasse von JFrame ableiten. 3. Die einzelnen Komponenten (Container, Labels, Buttons etc.) erzeugen und konfigurieren. 4. Die Komponenten in unterschiedliche Container einfügen. 5. Die Komponenten innerhalb des Containers anordnen. 6. Festlegen, welche Komponenten welche Ereignisse auslösen und Listener zur Abarbeitung der Ereignisse implementieren. Aufgabe 1.4 (Radio-Buttons) (3 P-Punkte) Radio-Buttons werden analog zu Check-Boxen erzeugt. Man kann sie auch genauso setzen wie Check- Boxen. Ihre Eigenschaft, dass jeweils nur einer selektiert ist (selektieren erfolgt für jeden Radio- Button programmtechnisch über die Methode setselected(boolean)), erhalten sie dadurch, dass sie Objekten vom Typ ButtonGroup mittels add(...) hinzugefügt werden. Innerhalb einer ButtonGroup kann dann jeweils nur ein Radio-Button selektiert sein. Implementieren Sie das Fenster aus Abb. 2, indem Sie den Konstruktor der Klasse radiobuttonframe passend ergänzen. Hierbei soll jeweils nur einer der Radio-Buttons A oder B, 1, 2 oder 3 und a oder b selektierbar sein. Achten Sie außerdem auf das Layout.