Vorlesung Grundlegende Programmiertechniken

Werbung
Vorlesung 13. Sitzung
Grundlegende
Programmiertechniken
Wintersemester 2007/2008
Dozent
Nino Simunic M.A.
Computerlinguistik, Campus DU
Grundlegende
Programmiertechniken, WS 2007/2008
GUI-Entwicklung mit Swing
GUI–Programmierung mit Swing
GUI: Schnittstelle zwischen Benutzer und
Programm
Beispiele?
-3-
Kommunikation mit Programm über Texteingabe,
Knopfdruck, Regler-Manipulation, etc.
Darstellung von Programm-Ergebnisse (nicht nur
textuell) möglich.
Word, Browser, Bildbetrachter, …
Womit GUIs in Java programmieren?
JFC (Java Foundation Classes). Bestehen im Kern
aus den Teilen:
-4-
AWT,
Swing
2D API,
Accessability,
Drag&Drop
Wesentlichen Bestandteile/Aspekte einer GUI
Fenster
Layout
Nehmen Container auf, welche
wiederum weitere Container
enthalten können.
Anordnung von Steuerelementen und
enthaltenen Containern via Layout
Manager
Graphische Benutzeroberfläche
Eventhandling,
(Ereignisverarbeitung)
Verarbeitung von durch Quellen
initiierte Ereignise (Knopfdruck,
Reglermanipilation, …)
-5-
Steuerelemente
Knöpfe, Regler, Dialoge als Quellen
der Interaktion. Senden Ereignisse
bei »Betätigung«.
Illustration der Aspekte an einer Pseudo-GUI
Ereignisverarbeitung
Ereignis
GUI
Container
Knopf
Layout
Kontroll-/Steuerelement,
Ereignis-Quelle
(Basis-)Fenster
-6-
Allgemeine Vorgehensweise bei der GUI-Entwicklung
Spezifizierung des Designs und der Anordnung
Spezifizierung der Benutzerinteraktionen
Reaktionen auf Ereignisse?
Erstellen des Basisfensters
JFrame, JApplet, JDialog, …
Hinzufügen der Elemente zum Container
Hinzufügen der Container zum Basisfenster
-7-
Logisch zusammenhängende Elemente werden in einem
Container zusammengefasst.
Anordnung innerhalb eines Containers mit einem
LayoutManager
Mit Container ist die Subklasse von Component gemeint
awt.Component
Component bietet grundlegende Methoden
Für die Darstellung von Komponenten am Bildschirm
Vorbereitung der Komponente fr Benutzerinteraktionen
Unterstützung für das Zeichnen, …
awt.Component
awt.2DGraphics
awt.Window
awt.Frame
swing.JFrame
-8-
awt.Container
swing.JComponent
awt.Container
Container: Subklassen von Component
Ein Container ist eine Component, die
Components aufnehmen kann
Zwei Sorten von Containern:
-9-
Dient der Strukturierung des Oberfläche
Stellt Methoden bereit, um Komponenten hinzuzufügen,
zu positionieren, zu entfernen, zu gruppieren
Komponenten werden als eine einzelne Einheit durch
den Container zusammengefasst
Top-Level Container
Intermediate-level Container
Top-Level Container
Benutzeroberflächen in Java besitzen immer
(mindestens) einen Top-Level-Container in der
containment hierarchy (gleich)
»Content Pane« (Inhaltsfläche)
Swing Top-Level Container: JFrame, JDialog, JApplet
Zweck: Darstellung der sichtbaren Komponenten
Inhaltsflächen sind intermediate container
Menüleiste: Nicht Teil der Inhaltsfläche
Top-Level
Container
und Basisfenster
Content
Pane
Menu Bar
-1010-
RootPane/LayeredPane fehlen in der
vorliegenden Darstellung
http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html
Komponenten hinzufügen: containment hierarchy
To appear onscreen, every GUI component
must be part of a containment hierarchy. A
containment hierarchy is a tree of components that
has a top-level container as its root.[1]
Yellow Label
-1111-
[1] http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html
Mehrere Top-Level Container in einer GUI?
[…] A Swing-based GUI has at least one containment
hierarchy with a JFrame as its root.
For example, if an application has one main window and two
dialogs, then the application has three containment
hierarchies, and thus three top-level containers.
One containment hierarchy has a JFrame as its root,
and each of the other two has a JDialog object as its root.[1]
M.a.W.: Immer nur ein Top-Level Container »ganz oben«
in der Hierarchie. Weitere Komponenten müssen in einer
dieser Hierarchien vorhanden sein.
-1212-
Ist das nicht der Fall, ist die Komponente schlichtweg nicht sichtund sinnvoll nutzbar.
[1] http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html
Hinzufügen einer Komponente
Zunächst: Sie fügen Komponenten nicht dem
Basisfenster direkt hinzu, sondern der
content pane (Inhaltsfläche)
TLC haben eine standard Inhaltsfläche (engl.
default content pane), welche dazu genutzt werden
kann.
-1313-
Simpler intermediate container,
erbt von Jcomponent,
BorderLayout ist Layout Manager
Default content pane erhält man via
getContentPane Methode
Hinzufügen einer Komponente: Beispielchen
Der wesentliche Code zum Hinzufügen des
»Yellow label« im letzten Beispiel:
frame.getContentPane().
add(yellowLabel, BorderLayout.CENTER);
frame ist der TLC (Hier ein JFrame-Objekt)
void add(Component c)
Container Methode. Wird an JFrame, JPanel,…,
vererbet.
Anweisung ist seit einigen Versionen identisch zu:
frame.add(yellowLabel,BorderLayout.CENTER);
-1414-
Der restliche Quelltext: TopLevelDemo.java (ohne Menu)
import java.awt.*; import javax.swing.*;
public class TopLevelDemo {
public static void main(String[] args) {
//Create and set up the window.
JFrame frame = new JFrame("TopLevelDemo");
frame.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
//Create a yellow label to put in the content pane.
JLabel yellowLabel = new JLabel();
yellowLabel.setOpaque(true); // default: durchsichtig
yellowLabel.setBackground(new java.awt.Color(248, 213, 131));
yellowLabel.setPreferredSize(new java.awt.Dimension(200, 180));
//Add label to top-level c.
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
//Display the window.
frame.pack();
frame.setVisible(true);
}
}
-1515-
Anmerkung zu getContentPane
getContentPane return't ein Container Objekt,
und kein JComponent Objekt.
Folglich müssen Sie zu JComponent casten, um
alle Features nutzen zu können.
Auch möglich: Sie können die default content Pane
durch eine eigene Komponente ersetzen (gleich).
Das ersetzen geschieht via Methode
setContentPane
-1616-
Einige wichtige Eigenschaften für Fenster:
Wichtige Eigenschaften der Klasse Window
Methoden
void pack()
Gibt dem Fenster die Größe, die zur Darstellung der
enthaltenen Komponenten notwendig ist
void dispose()
Löscht das Fenster und gibt die belegten Resourcen frei
awt.Component
awt.Container
awt.Window
awt.Frame
swing.JFrame
-1717-
swing.JComponent
Wichtige Eigenschaften der Klasse JFrame
Objekte der Klasse JFrame: frei bewegliche Fenster mit
Rahmen und Titelleister
Konstruktoren
Methoden
-1818-
JFrame( )
JFrame(String title)
void setTitle( String title )
String getTitle( )
void setSize( int x, int y )
void setLocation( int x, int y )
setVisible( boolean b )
setDefaultCloseOperation(int i)
setDefaultCloseOperation(int i)
Anstatt von int sind mehrsagendere Konstanten
nützlich:
javax.swing.WindowConstants.DISPOSE_ON_CLOSE
Entspricht dem Wert 2
javax.swing.WindowConstants.HIDE_ON_CLOSE
Enstpricht dem Wert 1
...
-1919-
Default content pane austauschen (1)
Sie wollen die default content pane Ihres TLC
ersetzen.
Bspw. eine Inhaltsfläche mit Rand und/oder eigenem
Layout Manager
Bspw. ein JPanel (Subklasse von JComponent)
Theoretisch können Sie auch JButton verwenden, das
macht aber als Inhaltsfläche eher weniger Sinn.
Warum macht JPanel mehr Sinn?
-2020-
Klasse JPanel
Einfachste Form eines Containers. Nichtsdestotrotz
nützlich und typisch in Java-GUIs
-2121-
Subklasse von JComponent
JPanel können weitere Container (JButton,
JPanel, JSplitPane, …) hinzugefügt werden,
ineinander verschachtelt werden, etc.
Um ein Panel anzeigen zu können, muss es
natürlich in einer containment hierarchy sein.
Default content pane austauschen (2)
Relevanter Code zur Erzeugung eines JPanel mit
Rand und anderem Layout Manager:
JPanel myContentPane = new JPanel();
myContentPane.
setBorder(BorderFactory.createTitledBorder("MyPane"));
myContentPane.setLayout(new java.awt.BorderLayout());
Nebenbei: Container haben standard-Layouts.
JPanel's standard-Layout ist FlowLayout
Das Ersetzen der Inhaltsfläche durch Ihre eigene:
basisFenster.setContentPane(myContentPane);
-2222-
Das Beispiel im Programm
import
import
import
import
javax.swing.BorderFactory;
javax.swing.JFrame;
javax.swing.JPanel;
java.awt.BorderLayout;
»Look&Feel« meines Betriebssystem.
Aussehen kann demnach – je nach
Umgebung – variieren.
public class PaneTest {
public static void main(String[] args) {
JFrame basisFenster = new JFrame();
JPanel myContentPane = new JPanel();
myContentPane.setBorder(BorderFactory.createTitledBorder("MyPane"));
myContentPane.setLayout(new BorderLayout());
basisFenster.setContentPane(myContentPane);
basisFenster.setSize(100, 100);
basisFenster.setVisible(true);
Mit default content pane
}
(bspw. durch Weglassen
des setContenPane
}
Aufrufs im Code):
-2323-
Layout und Layout Manager
Layout von Elementen innerhalb eines Container
werden via Layout Manager realisiert
Das Content Pane eines Container wie Frame
oder JFrame fragt bei einer Neudarstellung von
seinen Elementen immer seinen Layoutmanager,
wie er sie anordnen soll .
Jeder Layout Manager implementiert eine
unterschiedliche Strategie zur Anordnung. Bspw.
-2424-
Bspw. Buttons zentriert, oder von links nach rechts, …
FlowLayout
GridLayout
BorderLayout, ...
Verschiedene (Standard-)Layouts
FlowLayout
GridLayout
Tabellarisch: Zeilen,
Spalten
new GridLayout(2,3)
BorderLayout
-2525-
von links nach rechts, zentriert
Richtungsangabe via
Kompassrichtung
someJFrame.add(new JButton("1"),
BorderLayout.EAST);
1
2
3
1
2
3
4
5
6
NORTH
WEST CENTER
SOUTH
1
EAST
GridTest.java
import java.awt.GridLayout;
import javax.swing.*;
public class GridTest extends JFrame {
GridTest(){
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
JLabel lA = new JLabel("A"),
lB = new JLabel("B"),
lC = new JLabel("C"),
lD = new JLabel("D");
GridLayout lay = new GridLayout(2,2);
this.getContentPane().setLayout(lay);
this.getContentPane().add(lA); this.getContentPane().add(lB);
this.getContentPane().add(lC); this.getContentPane().add(lD);
this.setSize(200,200);
this.setVisible(true);
}
public static void main(String[] args) {
new GridTest();
}
-2626}
Weitere Layouts (GridTest-Beispiel als Basis)
GridLayout lay = new GridLayout(0,1);
FlowLayout lay = new FlowLayout(FlowLayout.CENTER);
GridLayout lay = new GridLayout(1,0);
BorderLayout lay = new BorderLayout(10,10);
this.getContentPane().setLayout(lay);
this.getContentPane().add(lA, lay.WEST);
this.getContentPane().add(lB, lay.EAST);
this.getContentPane().add(lC, lay.NORTH);
this.getContentPane().add(lD, lay.SOUTH);
-2727-
Steuerelemente
Steuer- bzw. Kontrollelemente sind Entitäten der
JComponent- Hierarchie
Dienen der Ein-/Ausgabe von Daten über
Bildschirm, Tastatur, Maus.
I.d.R. aktive Elemente
-2828-
Bspw. JButtons, JLabels, JSlider, etc.
Benutzer kann sie bspw. mit der Maus anklicken und
dadurch ein Ereignis auslösen
Ereignisbasierte Programmierung
Konzepte ereignisbasierter Programmierung
Senden und Empfangen der Ereignisse geschieht nach
Auslösen der Aktion (fast) automatisch. Voraussetzung:
-2929-
Es gibt eine Ereignisquelle
Die Ereignisquelle kann Ereignisse auslösen
Es gibt einen Ereignisempfänger
Der Empfänger muss die Quelle »kennen«
Der Ereignisempfänger empfängt das Ereignis und führt
entsprechende Aktionen durch
Komponente muss Ereignisse versenden können
Empfänger muss Ereignisse verarbeiten können
Empfänger muss bei der Quelle registriert sein
Illustration: Ereignisbasierte Programmierung, generisch
Registrierung
Ereignisquelle
Ereignisempfänger
Erzeugt Ereignis
Behandelt Ereignis
Benachrichtigung (notification )
-3030-
Programmtechnische Umsetzung: Quelle, Ereignis, Empfänger
Ereignisempfänger werden als Listener implementiert:
Listener registriert sich bei der Quellkomponente
Methode enthält die durchzuführenden Anweisungen
Erwartet Objekt vom Typ Event als Argument
Unterschiedliche Quellformen produzieren verschiedene
Events und benötigen entsprechende Listener
-3131-
Komponente stellt Methode für die Registrierung zur Verfügung
Auslösen einer Aktion führt zum Aufruf einer a priori zu
implementierenden »Aktions-Methode« des Listeners
Sind zu implementierende Interfaces aus java.awt.event.*
Bsp. Knopfdruck: ActionEvent, ActionListener
Event Klassen: Überblick
-3232-
Listener im Überblick
-3333-
Schrittweise Implementierung von Event-(Re-)Aktionen
(1)
(2)
(3)
-3434-
Klasse, die auf das Event reagieren soll,
implementiert das jeweilige Interfaces
In Methode(-n) des Interface die Reaktion
programmieren
Listener-Objekt erzeugen und bei Instanz der
Ereignisquelle registrieren
Quelle benachrichtigt Empfänger immer, wenn
Ereignis ausgelöst wird
Implementierungsbeispiel
GUI mit Knopf und Textfläche
Knopfdruck bewirkt Textausgabe in der Textfläche
-3535-
Angabe, wie oft der Knopf gedrückt wurde
Benötigt: Container/Steuerelemente, Layout,
Listener-Implementierung und -Registrierung
ButtonEventTest.java
Listener
class ButtonEventTest extends JFrame implements ActionListener {
private JButton button1; private JTextPane jtp; private int butClicks;
ButtonEventTest() {
Ereignis-Quelle:
/* Button, Textfläche erzeugen*/
button1 = new JButton("PUSH");
JButton
jtp = new JTextPane();
jtp.setEditable(false); // nur lesen, nicht schreiben
// Zur Inhaltsfläche hinzufügen
getContentPane().add(button1, BorderLayout.NORTH);
getContentPane().add(jtp, BorderLayout.CENTER);
/* Listener registrieren */
Listener bei der Quelle
button1.addActionListener(this);
registrieren
/* Eigenschaften des Fensters: */
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(100, 100));
setVisible(true);
}
public void actionPerformed(ActionEvent arg0) {
jtp.setText("Gedrückt: "+butClicks++ );
}
}
}
-3636-
Reaktion auf das Ereignis.
Obligatorisch zu
implementierende
Methode.
Komponenten und Ereignisse
JAbstractButton
Action Event
actionPeformed
Change Event
stateChanged
Item Event
itemStateChanged
JTextComponent
Caret Event
caretUpdate
JTextField
Action Event
actionPerfomed
-3737-
Zukünftiges (1)
Die Testataufgabe kann ab Freitag, 15.02.2008, 15.00
Uhr, downgeloadet werden
Bearbeitungszeit voraussichtlich 21 Tage
Bei Verdacht auf Diebstahl bzw. Weitergabe geistigen Eigentums
werden Teilnehmer zu Ihrer Testat-Lösung mündlich geprüft.
Es wird erwartet, dass Sie sich in neue Themen einarbeiten
»Neu«: Bislang ungesehene Klassen zur Datenstrukturierung
(Collection-Framework), Generezität im Kontext Collections, GUIEntwicklung (Textfelder, Regler, …)
Sie werden dazu nat. nützliche Literatur bzw. Literaturhinweise
bekommen
Alle relevanten Informationen (Bearbeitungszeit,
Abgabemodalitäten, … ) zum angegebenen Zeitpunkt auf
unserer Seite unter »Aktuelles«:
http://www.uni-due.de/computerlinguistik/prog0708.shtml
-3838-
Zukünftiges (2)
Es wird wieder Wiederholungstutorien geben.
Vorläufige Termine sind kommenden Donnerstag
(14.02.) und Freitag (15.02.), jeweils 3h.
-3939-
Die genauen Termine werden kommenden Montag auf
»unserer« Seite bekanntgegeben.
Voraussichtlich morgens (10.00-13.00)
Teilnehmerzahlen sind jeweils beschränkt auf maximal
25 Personen! Sprechen Sie sich im Informatik-Forum
bitte ab.
Herunterladen