GUI Design
Universität Paderborn
Prof. Dr. Stefan Böttcher
Java Swing und AWT
1
Gui Design
Universität Paderborn
Prof. Dr. Stefan Böttcher
Von „Hand“
Mittels
visuellem
GUI
Designer
2
Warum „von Hand“?
Universität Paderborn
Prof. Dr. Stefan Böttcher
Grundkonzepte erlernen
Zum Verständnis des von GUI Designern
generierten Codes unerlässlich
GUI Designer können oft nicht alles
z.B. bei Programmierung und Einsatz
von eigenen GUI Komponenten
Dynamische GUI Erstellung
zur Laufzeit möglich
z.B. indem Eingabemasken durch
Datenbankinhalte bestimmt werden
Grundlagen der Programmierung 2 im SS 2008
3
Ereignisse
Universität Paderborn
Prof. Dr. Stefan Böttcher
Programmbedienung mittels
Zeigen, Klicken, Draggen, Tippen, Einrahmen,…
Benutzer löst Ereignisse aus
Ereignisse müssen abgefangen, erkannt, den richtigen
Einheiten zugeordnet und von diesen interpretiert
werden
Grundlagen der Programmierung 2 im SS 2008
4
Swing
Universität Paderborn
Prof. Dr. Stefan Böttcher
Nachfolger des awt (Abstract Window Toolkit)
Wählbares Look & Feel (Motif, Windows, Java, ...)
Klassen entspr. Graphischen Komponenten
Einbinden von Swing-Komponenten durch
import javax.swing.*;
class Swing1 {
public static void main(String[] args) {
JFrame frame = new JFrame("Das Programm");
JLabel label = new JLabel("Hello World!");
frame.getContentPane().add(label);
Swing1.java
frame.setSize(300,100);
frame.setVisible(true);
}
}
Grundlagen der Programmierung 2 im SS 2008
5
JFrame und JLabel
Universität Paderborn
Prof. Dr. Stefan Böttcher
import javax.swing.*;
public class FirstSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("Das Programm");
/* JFrame implementiert gerahmte Fenster
Titel wird festgelegt beim Erzeugen (Konstruktor),
später mit setTitle(…) */
JLabel label = new JLabel("Hello World!");
/* JFrame implementiert Textanzeige
Titel wird festgelegt beim Erzeugen (Konstruktor),
später mit setText(…) */
frame.getContentPane().add(label);
/* JFrame ist eine eine Container-Klasse
sie kann andere Swing-Komponenten aufnehmen
und anzeigen indem man die Swing-Komponente
dem ContentPane des Frames hinzufügt.*/
frame.setSize(300,100); //300x100 Pixel
frame.setVisible(true); //Sichtbarkeit
}}
Grundlagen der Programmierung 2 im SS 2008
6
Beenden ?
Grundlagen der Programmierung 2 im SS 2008
Universität Paderborn
Prof. Dr. Stefan Böttcher
7
Beenden!
Universität Paderborn
Prof. Dr. Stefan Böttcher
Frame lebt eigenständig weiter (Thread!) bis er
beendet wird
Swing2.java
import javax.swing.*;
public class FirstSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("Das Programm");
JLabel label = new JLabel("Hello World!");
frame.getContentPane().add(label);
frame.setSize(300,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}}
Grundlagen der Programmierung 2 im SS 2008
8
Komponenten
Universität Paderborn
Prof. Dr. Stefan Böttcher
Component: Objekt mit graphischer
Repräsentation (AWT und Swing);
verschickt und empfängt Events
Container: Behälter für andere
Components;
kann LayoutManager benutzen
JComponent: Basisklasse für alle
Swing-Komponenten; kann Look and
Feel setzen
JFrame, JDialog,
JApplet: top-level Swing-Container
JPanel: eingebetteter Swing-Container
JLabel, JTextField, JButton, …:
Swing-Komponenten
Grundlagen der Programmierung 2 im SS 2008
9
10 Labels erzeugen
Universität Paderborn
Prof. Dr. Stefan Böttcher
10 Labels erzeugen, Kontrolle durch Textausgabe
…
JFrame frame = new JFrame("Das Programm");
for (int i=0; i < 10; i++) {
frame.getContentPane().add(new JLabel("Label "+(i+1)));
System.out.println("Label "+(i+1)+" erzeugt."); }
frame.setSize(300,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
…
Swing3x.java
Grundlagen der Programmierung 2 im SS 2008
10
Layouts
Universität Paderborn
Prof. Dr. Stefan Böttcher
„Fehler“: Standardmäßige Platzierung in der Mitte
des contentPane
Lösung: Umschalten auf „FlowLayout“:
import java.awt.*;
…
JFrame frame = new JFrame("Das Programm");
frame.getContentPane().setLayout (new FlowLayout());
for (int i=0; i < 10; i++) {
frame.getContentPane().add(new JLabel("Label "+(i+1)));
System.out.println("Label "+(i+1)+" erzeugt."); }
frame.setSize(300,100);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
…
Swing3.java
Grundlagen der Programmierung 2 im SS 2008
11
Layout Manager
Universität Paderborn
Prof. Dr. Stefan Böttcher
Verantwortlich für Dialogelementanordnung
Jeder LayoutManager besitzt eigene
Platzierungsstrategie
Standard-LayoutManager:
FlowLayout
GridLayout
BorderLayout
CardLayout
GridBagLayout
Null-Layout: direkte Angabe der Pixel
Grundlagen der Programmierung 2 im SS 2008
12
FlowLayout
Universität Paderborn
Prof. Dr. Stefan Böttcher
Odnet Dialogelemente
nebeneinander in einer Zeile an
Passen keine weiteren Elemente in eine Zeile:
Fahre mit der nächsten Zeile fort
Grundlagen der Programmierung 2 im SS 2008
13
Universität Paderborn
Prof. Dr. Stefan Böttcher
GridLayout
Ordnet Dialogelemente in
rechteckigem n mal m Gitter an
GridBagLayout ist komplexe
Erweiterung des GridLayout
GridLayout(int rows, int cols)
GridLayout(int rows, int cols, int hgap, int vgap)
hgap=horizontal gap between components
vgap=vertical gap between components
rows=number of rows in the grid
cols=number of column in the grid
Grundlagen der Programmierung 2 im SS 2008
14
Universität Paderborn
Prof. Dr. Stefan Böttcher
BoxLayout
Elemente werden nebeneinander (X_AXIS) oder
untereinander (Y_AXIS) angeordnet
Größe der Einzelelemente wird respektiert
frame.getContentPane().setLayout(
new BoxLayout(frame.getContentPane(),
BoxLayout.X_AXIS));
Y_AXIS
Grundlagen der Programmierung 2 im SS 2008
X_AXIS
15
Border Layout
Universität Paderborn
Prof. Dr. Stefan Böttcher
Verteilt Dialogelemente nach auf vier
Randbereiche und Mittelbereich des Fensters:
NORTH, SOUTH, WEST, EAST, CENTER
import javax.swing.*; import java.awt.*;
...
JFrame frame = new JFrame("Das Programm");
frame.getContentPane().setLayout (new BorderLayout());
frame.getContentPane().add(new
frame.getContentPane().add(new
frame.getContentPane().add(new
frame.getContentPane().add(new
frame.getContentPane().add(new
JLabel("Label Süd"), BorderLayout.SOUTH);
JLabel("Label Nord"), BorderLayout.NORTH);
JButton("Zentrum"), BorderLayout.CENTER);
JLabel("West"), BorderLayout.WEST);
JLabel("Ost"), BorderLayout.EAST);
Grundlagen der Programmierung 2 im SS 2008
16
Eigener Fenstertyp
Universität Paderborn
Prof. Dr. Stefan Böttcher
import java.awt.*;
import javax.swing.*;
public class Swing4 extends JFrame{
static int fensterNummer = 0;
Swing4(String s) {
super(s); //JFrame Konstruktor
fensterNummer++; //zählt Fenster
getContentPane().setLayout(new FlowLayout());
getContentPane().add(new JLabel("Label"));
setSize(200,200);
setLocation(50*fensterNummer, 50*fensterNummer);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE); //beendet Programm BEIDE Fenster
}
public static void main(String[] args) {
new Swing4("Fenster 1");
new Swing4("Fenster 2");
}
Swing4.java
}
Grundlagen der Programmierung 2 im SS 2008
17
Zeichnen
Universität Paderborn
Prof. Dr. Stefan Böttcher
Einbinden einer Zeichenfläche (JPanel)
als eigener JPanel-Typ ("MyPanel")
getContentPane().add(new MyPanel());
JPanel besitzt paint-Methode, automatischer Aufruf durch
Window-Manager sobald nötig:
Erster Aufbau des Panels
"Aufdecken" eines Teils des Panels
Scrollen
Größer ziehen
Vordefinierte paint-Methode ist leer
(zeichnet nichts), überschreiben:
public void paint(Graphics g)
{
g.drawLine(0, 0, 200, 200);
g.drawLine(0, 200, 200, 0);
}
Grundlagen der Programmierung 2 im SS 2008
18
Paint Methode erstellen
Universität Paderborn
Prof. Dr. Stefan Böttcher
import java.awt.*;import javax.swing.*;
public class MyFrame extends JFrame{
static int fensterNummer = 0;
MyFrame(String s){
super(s);
getContentPane().add(new MyPanel());
fensterNummer++;
setSize(300,300);
setLocation(50*fensterNummer, 50*fensterNummer);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
class MyPanel extends JPanel {
public void paint(Graphics g){
g.drawLine(0, 0, 200, 200);
g.drawLine(0, 200, 200, 0);}
}
public static void main(String[] args) {
new MyFrame("Fenster 1");
new MyFrame("Fenster 2");
}
Swing5.java
}
Grundlagen der Programmierung 2 im SS 2008
19
Universität Paderborn
Prof. Dr. Stefan Böttcher
Diagonalen zeichnen
"Feststehende" Linien – unabhängig von Fenstergröße
Variante: Zeichnen echter Diagonalen
g.drawLine (0, 0, getWidth(), getHeight() );
g.drawLine(getWidth(), 0, 0, getHeight() );
Punkt links oben: (0,0)
Punkt rechts unten: (getWidth(), getHeight())
Dynamische Linien –
Neuzeichnen bei jeder Änderung
der Fenstergröße
Swing5a.java
Grundlagen der Programmierung 2 im SS 2008
20
Klassenhierarchie
Universität Paderborn
Prof. Dr. Stefan Böttcher
Verschiedene Ebenen der
Vererbungshierarchie
Object (lang) - die allgemeinste
Java-Klasse
Component (awt) - die eigentlichen
GUI-Elemente (Widgets)
Container (awt) - Komponenten, die
wieder andere Komponenten
aufnehmen können
Window (awt) - Fenster ohne Rand
Frame (awt) - Fenster mit Rand,
http://java.sun.com/j2se/5.0/docs/api/
Titel, Menüleiste, veränderbarer
Größe
JFrame (swing) - Erweiterung der
(älteren) Frame-Klasse des awt, die
Frames in die JFC-Umgebung
einbindet
Grundlagen der Programmierung 2 im SS 2008
21
AWT GUI Komponenten
Grundlagen der Programmierung 2 im SS 2008
Universität Paderborn
Prof. Dr. Stefan Böttcher
22
Universität Paderborn
Prof. Dr. Stefan Böttcher
Swing Widgets 1
JScrollPane:
JPasswordField:
Grundlagen der Programmierung 2 im SS 2008
JTextPane:
JEditorPane:
23
Swing Widgets 2
Universität Paderborn
Prof. Dr. Stefan Böttcher
JScrollBar:
JProgressBar:
JSlider:
JComboBox:
Grundlagen der Programmierung 2 im SS 2008
24
Swing Widgets 3
JList:
Universität Paderborn
Prof. Dr. Stefan Böttcher
JList mit Grafiken:
JMenu:
Grundlagen der Programmierung 2 im SS 2008
25
Universität Paderborn
Prof. Dr. Stefan Böttcher
Swing Widgets 4
JPopupMenu:
JTree / JSplitPane:
Grundlagen der Programmierung 2 im SS 2008
JSeperator:
JTabbedPane:
26
JTabbedPanel Beispiel
Universität Paderborn
Prof. Dr. Stefan Böttcher
…
getContentPane().setLayout (new BorderLayout());
JTabbedPane contentPanel= new JTabbedPane();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
panel1.add(new JLabel("Ich bin Panel 1"));
panel2.add(new JLabel("Ich bin Panel 2"));
contentPanel.add("Erstes Panel",panel1);
contentPanel.add("Zweites Panel",panel2);
getContentPane().add(contentPanel);
…
Grundlagen der Programmierung 2 im SS 2008
27
Beispiel: Zielscheibe (1)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Grundidee:
Zeichnen kleiner werdender
konzentrischer, gefüllter Kreise mit
abwechselnden Farben
(schwarz, weiß)
Zeichnen eines Kreises:
Suchen in Java-Dokumentation
Graphics-Objekte können gefüllte
Kreise (Ellipsen) zeichnen!
Grundlagen der Programmierung 2 im SS 2008
28
Beispiel: Zielscheibe (2)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Kreis um den Punkt (mx, my) mit Radius r
fillOval(mx-r, my-r, 2*r, 2*r);
Grundlagen der Programmierung 2 im SS 2008
29
Beispiel: Zielscheibe (3)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Idee: Kreis erzeugen, dann drawMe(..) aufrufen mit Füllfarbe und dem
Graphics-Object, „in das“ gezeichnet werden soll.
Graphik1.java
…
class Circle
{
private int x, y;
private double r;
Circle(int ix, int iy, double ir) {
x = ix; y = iy; r = ir;
System.out.println("Kreis um ("+x+", "+y+") mit Radius: "+r);
}
void drawMe (Graphics g, Color c) {
g.setColor(c);
g.fillOval((int)(x-r), (int)(y-r), (int)(2*r), (int)(2*r));
}
}…
Grundlagen der Programmierung 2 im SS 2008
30
Beispiel: Zielscheibe (4)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Wiederverwendung der MyFrame-Klasse, sowie
einer eigenen Komponente Zeichenfläche
Graphik1.java
class MyFrame extends JFrame {
MyFrame(String s) {
...
getContentPane().add(new Zeichenfläche());
...
}
class Zeichenfläche extends JPanel {
public void paint(Graphics g) {
for (int i=10; i>0; i--)
{
new Circle(150, 150, i*10.0+5.0).
drawMe(g, ( i%2==0 ) ? Color.black : Color.white);
}
if( i%2 == 0 ) //i modulo 2
}
{… Color.black} else
}
{… Color.white}
Grundlagen der Programmierung 2 im SS 2008
31
Beispiel: Zielscheibe (5)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Variante, die variable Ringanzahlen zeichnet:
class MyFrame extends JFrame {
Zeichenfläche z = new Zeichenfläche();
// Objektvariable!
public void setAnzahlRinge(int ar) {z.setAnzahlRinge(ar);}
MyFrame() { ... }
}
class Zeichenfläche extends JPanel {
int anzahlRinge = 20;
Graphik2.java
public void setAnzahlRinge(int ar) {anzahlRinge=ar;}
public void paint(Graphics g)
{
for (int i=anzahlRinge; i>0; i--)
{
new Circle(150, 150, i*anzahlRinge+5.0).
drawMe(g, (i%2==0)?Color.black:Color.white);
}
}
}
Grundlagen der Programmierung 2 im SS 2008
32
Beispiel: Zielscheibe (6)
Universität Paderborn
Prof. Dr. Stefan Böttcher
Eingabe der Ringzahlen im Hauptprogramm
MyFrame f = new MyFrame("Fenster mit Zielscheibe");
while (true)
{
System.out.print("Wieviele Ringe?");
Graphik2.java
f.setAnzahlRinge(in.nextInt());
}
Problem: Gezeichnet wird immer erst nach Verdecken,
Verschieben, Scrollen, etc...
Expliziter Aufruf von paint(...) nicht möglich
Lösung: repaint() erzwingt Aufruf von paint(...) zum
nächstmöglichen Zeitpunkt!
MyFrame f = new MyFrame("Fenster mit Zielscheibe");
while (true)
{
System.out.print("Wieviele Ringe?");
f.setAnzahlRinge(in.nextInt());
f.repaint();
}
Grundlagen der Programmierung 2 im SS 2008
33
Zusammenfassung
Universität Paderborn
Prof. Dr. Stefan Böttcher
Erste Swing Programme
JFrame und JLabel
Graphische Komponentenhierarchie
Überblick über Layout Manager
Zeichnen mittels paint() Methode
Überblick über Swing Widgets
Zielscheibenbeispiel
Komplexere Zeichnungen
Repaint()
Grundlagen der Programmierung 2 im SS 2008
34
Buttons (1) - Ziel
Universität Paderborn
Prof. Dr. Stefan Böttcher
Ziel: Steuerung durch Buttons
Textausgabe mit Labeln
Anzeigen von Buttons
Programmieren der Reaktion auf Buttons
Anordnung (Layout) dieser Elemente
Grundlagen der Programmierung 2 im SS 2008
35
Buttons (2) - Ablauf
Universität Paderborn
Prof. Dr. Stefan Böttcher
Ablauf
1. Erzeugen einer eigenen Fensterklasse, mit einer Zeichenfläche, diese
wiederum mit geeigneter paint-Methode
2. Erstellen des Dialogfensters
3. Anbindung der Aktionen an die Buttons
4. Beeinflussen des Layouts der Dialogbox
Entwicklungsschritt 1: Erzeugen einer Fensterklasse und
Zeichenfläche, deren paint()-Methode die Zielscheibe zeichnet
Zusätzlich: Objektvariablen in Zeichenfläche (Pos. und Anzahl Ringe)
Dafür: Get- und Set-Methoden (in Zeichenfläche und MyFrame)
Konsequenz: Aufrufe für setxPos(…), setyPos(…) oder
setAnzahlRinge(…) müssen die Zielscheibe neu zeichnen.
Grundlagen der Programmierung 2 im SS 2008
36
Buttons (3) - myFrame
Universität Paderborn
Prof. Dr. Stefan Böttcher
Klasse myFrame
class MyFrame extends JFrame {
StrgZielscheibe.java
Zeichenfläche z = new Zeichenfläche();
//getpublic
public
public
public
public
public
und set- Methoden
void setAnzahlRinge(int ar) {z.setAnzahlRinge(ar); repaint();}
int getAnzahlRinge() { return z.getAnzahlRinge();}
void setxPos(int x) { z.setxPos(x); repaint();}
void setyPos(int y) { z.setyPos(y); repaint();}
int getxPos() { return z.getxPos();}
int getyPos() { return z.getyPos();}
MyFrame(String s) { //Konstruktor
super(s);
getContentPane().add(z);
setSize(300,300);
setLocation(350, 250);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}
Grundlagen der Programmierung 2 im SS 2008
37
Buttons (4) - Zeichenfläche
Universität Paderborn
Prof. Dr. Stefan Böttcher
Klasse Zeichenfläche
class Zeichenfläche extends JPanel {
StrgZielscheibe.java
//get- und set-Methoden
private int anzahlRinge = 10;
public void setAnzahlRinge(int a) { anzahlRinge = Math.max(a, 0); }
public int getAnzahlRinge() { return anzahlRinge; }
private int xPos = 150, yPos = 150;
public void setxPos(int x) { xPos =
public void setyPos(int y) { yPos =
public int getxPos() { return xPos;
public int getyPos() { return yPos;
//Initiale Position
x; }
y; }
}
}
public void paint(Graphics g)
{
for (int i=anzahlRinge; i>0; i--)
new Circle(xPos, yPos, i*anzahlRinge+5.0).
drawMe(g, (i%2==0)?Color.black:Color.white);
}
}
Grundlagen der Programmierung 2 im SS 2008
38
Buttons (5) - Dialogfenster
Universität Paderborn
Prof. Dr. Stefan Böttcher
Dialogfenster MyDialog wird von JDialog abgeleitet
Buttons als Objektvariable
Buttons und Label dem ContentPane des Dialogfensters hinzufügen
class MyDialog extends JDialog
StrgZielscheibe.java
{
JButton blinks = new JButton("Links schieben");
JButton brechts = new JButton("Rechts schieben");
JButton bplus
= new JButton("Mehr Ringe");
JButton bminus = new JButton("Weniger Ringe");
JButton bhoch
= new JButton("Hoch schieben");
JButton brunter = new JButton("Runter schieben");
...
Buttons bis hier noch unsichtbar
Hinzufügen zu einem ContentPane für Sichtbarkeit
Label (konstante Texte) direkt erzeugen und dem ContentPane
hinzufügen, Referenzen darauf werden nicht gebraucht.
Grundlagen der Programmierung 2 im SS 2008
39
Buttons (6) - myDialog
Konstrukor von myDialog
Universität Paderborn
Prof. Dr. Stefan Böttcher
StrgZielscheibe.java
MyDialog(String s) {
getContentPane().setLayout(new FlowLayout());
getContentPane().add(
new Label("Verändern Sie die Anzahl der Ringe") );
getContentPane().add(bplus);
getContentPane().add(bminus);
getContentPane().add(
new Label("Verschieben Sie waagerecht"));
getContentPane().add(blinks);
getContentPane().add(brechts);
getContentPane().add(
new Label("Verschieben Sie senkrecht"));
getContentPane().add(bhoch);
getContentPane().add(brunter);
setSize(280,250); setTitle(s);
setLocation(10,10); setVisible(true);
}
Grundlagen der Programmierung 2 im SS 2008
40
Buttons (7) - Aktionen
• Anbindung der Aktionen an die Buttons
Universität Paderborn
Prof. Dr. Stefan Böttcher
StrgZielscheibe.java
• Prinzip: Erzeugen einer Klasse, die das ActionListener-Interface
implementiert
interface ActionListener
{ void actionPerformed(ActionEvent e); }
• Instanz der ActionListener Klasse wird Button zugeordnet, auf dessen
Drücken reagiert werden soll
• Bei Buttonklick wird die actionPerformed(...)-Methode der
zugeordneten ActionListener-Klasse aufgerufen
• Parameter ActionEvent e enthält zusätzliche Daten (z.B. welcher
Button, welche Maustasten, etc.)
• Methode actionPerformed(…) enthält Aktion, die der Button auslöst
•
z.B. Aufruf von setAnzahlRinge(...)
Grundlagen der Programmierung 2 im SS 2008
41
Buttons (8) - Aktionen
Universität Paderborn
Prof. Dr. Stefan Böttcher
• Button bplus soll Zahl der Ringe im Frame frame um 1 erhöhen:
frame.setAnzahlRinge(frame.getAnzahlRinge()+1);
• Entspricht folgender actionPerformed-Methode
void actionPerformed (ActionEvent e) {
frame.setAnzahlRinge(frame.getAnzahlRinge()+1);
}
• Muss in Klasse enthalten sein, die ActionListener-Interface implementiert
class X ... implements ActionListener { ... }
• Zuordnung von Objekt x der Klasse X zum Button bplus
bplus.addActionListener(x);
• Wird Button bplus gedrückt, wird die Methode actionPerformed(..) des
Objektes x der Klasse X ausgeführt.
Grundlagen der Programmierung 2 im SS 2008
42
Buttons (9) - Aktionen
Universität Paderborn
Prof. Dr. Stefan Böttcher
• Erweiterung: Wird Instanz x vielen Buttons als ActionListener
zugeordnet, muss erkennbar sein, welcher Button gedrückt wurde
• Idee: Setzen eines Strings ("ActionCommand") beim Button
bplus.setActionCommand(“PLUS“);
• Abfrage welcher Button gedrückt wurde in der Methode
actionPerformed(ActionEvent e) mit Methode e.getActionCommand()
liefert String, der mit Button als „ActionCommand“ verbunden wurde
if (e.getActionCommand().equals(“PLUS“))
{ ... Aktion für den bplus-Button ... }
else
if (e.getActionCommand().equals(„MINUS“))
...
Implementierung von ActionListener durch das Dialogobjekt selbst
class MyDialog extends JDialog implements
ActionListener {..}
Grundlagen der Programmierung 2 im SS 2008
43
Buttons (10) - actionPerformed
Universität Paderborn
Prof. Dr. Stefan Böttcher
actionPerformed-Methode von MyDialog
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("PLUS"))
frame.setAnzahlRinge(frame.getAnzahlRinge()+1);
else
if (e.getActionCommand().equals("MINUS"))
frame.setAnzahlRinge(frame.getAnzahlRinge()-1);
else
if (e.getActionCommand().equals("LINKS"))
frame.setxPos(frame.getxPos()-10);
else
if (e.getActionCommand().equals("RECHTS"))
frame.setxPos(frame.getxPos()+10);
else
if (e.getActionCommand().equals("HOCH"))
frame.setyPos(frame.getyPos()-10);
else
if (e.getActionCommand().equals("RUNTER"))
frame.setyPos(frame.getyPos()+10);
}
Grundlagen der Programmierung 2 im SS 2008
44
Buttons (11) - Konstruktor von MyDialog
Universität Paderborn
Prof. Dr. Stefan Böttcher
Buttons müssen Objekt selbst als ActionListener zugewiesen werden:
bplus.addActionListener(this);
bminus.addActionListener(this);
...
Buttons müssen zusätzlich ihr „ActionCommand“ zugewiesen werden:
bplus.setActionCommand("PLUS");
bminus.setActionCommand("MINUS");
...
actionPerformed()-Methode muss MyFrame kennen,
in das gezeichnet werden soll
⇒ Konstruktor von MyDialog bekommt Referenz darauf als Parameter
⇒ MyDialog speichert Referenz auf MyFrame als Objektvariable frame
MyDialog(MyFrame f, String s){ frame = f; ... }
Grundlagen der Programmierung 2 im SS 2008
45
Buttons (12) – Übersicht 1
Universität Paderborn
Prof. Dr. Stefan Böttcher
class MyDialog extends JDialog implements ActionListener {
JButton blinks = new JButton("Links schieben");
...
JButton brunter = new JButton("Runter schieben");
MyFrame frame;
MyDialog(MyFrame f, String s) {
getContentPane().add(
new Label("Verändern Sie die Anzahl der Ringe")
);
getContentPane().add(blinks);
...
getContentPane().add(brunter);
setSize(280,250); setTitle(s); setVisible(true);
blinks.addActionListener(this);
blinks.setActionCommand(“LINKS");
...
brunter.addActionListener(this);
brunter.setActionCommand("RUNTER");
frame = f;
StrgZielscheibe.java
}
Grundlagen der Programmierung 2 im SS 2008
46
Buttons (13) – Übersicht 2
Universität Paderborn
Prof. Dr. Stefan Böttcher
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("PLUS"))
frame.setAnzahlRinge(frame.getAnzahlRinge()+1);
else
...
if (e.getActionCommand().equals("RUNTER"))
StrgZielscheibe.java
frame.setyPos(frame.getyPos()+10);
}
}
Unschön: Buttons fließen bei Größenänderungen herum
Einfache Lösung:
Größenänderungen verbieten!
Im Konstruktor von MyDialog:
setResizable(false);
Grundlagen der Programmierung 2 im SS 2008
47
Buttons (14) – LayoutManager Beispiel
Universität Paderborn
Prof. Dr. Stefan Böttcher
Bislang FlowLayout
getContentPane().setLayout(new FlowLayout());
Grid Layout
setLayout(new GridLayout(3, 3));
aber: alle Felder sind gleich groß!
Grundlagen der Programmierung 2 im SS 2008
48
Buttons (14) – Schachtelung von Layouts
Universität Paderborn
Prof. Dr. Stefan Böttcher
Container kann andere Elemente (u.a. auch Container)
aufnehmen, einfachster Container: JPanel
Je ein JPanel für Ringzahl, Schieben-X, Schieben-Y
Pro JPanel jeweils ein Label und zwei Buttons
getContentPane().setLayout(
new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
JPanel anzahlPanel = new JPanel(new FlowLayout());
anzahlPanel.add(new Label("Verändern Sie die Anzahl der Ringe"));
anzahlPanel.add(bplus);
anzahlPanel.add(bminus);
getContentPane().add(anzahlPanel);
JPanel waagerechtPanel = new JPanel(new FlowLayout());
…
Grundlagen der Programmierung 2 im SS 2008
49
Buttons (15) – fertig!
Universität Paderborn
Prof. Dr. Stefan Böttcher
StrgZielscheibe2.java
Grundlagen der Programmierung 2 im SS 2008
50
Texteingabefelder
Universität Paderborn
Prof. Dr. Stefan Böttcher
Einzeilige Textfelder:
JTextField
mehrzeilige Textfelder: JTextArea
Abfangen von Ereignissen mit ActionListener-Objekten
Wiederholung: Anonyme Klassen
Klassen, die keinen Namen haben
Getrennt von der Klassendefinition können
keine Objekte erzeugt werden
Für Erzeugung genau eines Objektes dieser Klasse
Technik: Kombination von new X(...) und
Definition einer Unterklasse {…}
Grundlagen der Programmierung 2 im SS 2008
51
Wdh: Anonyme Klassen
class X
Universität Paderborn
Prof. Dr. Stefan Böttcher
{ public void m() { System.out.println("KLASSE X"); } }
class Test {
public static void main(String [] args) {
X xObject = new X () {
public void m()
{ System.out.println("Anonyme KLASSE"); }
};
xObject.m();
AnonymeKlasse.java
}
}
Was wird ausgegeben?
new X (): Erzeugen eines neuen Objektes vom Typ X
Aber: Überschreibung der Definition von X durch:
{ public void m() {
System.out.println("Anonyme KLASSE");}
};
Es entsteht Objekt einer unbenannten anonymen Klasse
Grundlagen der Programmierung 2 im SS 2008
52
Programmiertechnik für Listener 1
Universität Paderborn
Prof. Dr. Stefan Böttcher
Es existieren diverse Ereignistypen XXXEvent:
FocusEvent
KeyEvent
MouseEvent
WindowEvent, ...
Variante 1: Zu jedem Ereignistyp XXXEvent existiert ein
Interface XXXListener das mögliche Ereignisse aufzählt
Beispiel WindowEvent:
public interface WindowListener extends EventListener
{
void windowActivated (WindowEvent);
void WindowClosed (WindowEvent);
void windowClosing (WindowEvent);
...
void windowOpened (WindowEvent);
}
Grundlagen der Programmierung 2 im SS 2008
53
Programmiertechnik für Listener 2
Universität Paderborn
Prof. Dr. Stefan Böttcher
Grundidee:
1. Bilden einer Klasseninstanz, die dieses Interface erfüllt
2. Verknüpfen dieser Klasseninstanz mit einer GUI-Komponente, die diesen
Ereignistyp erzeugt
3. Die entsprechende Methode wird aufgerufen, sobald das zugehörige Ereignis
auftritt
Beispiel WindowListener:
class MyWindowListener implements WindowListener {
void windowActivated (WindowEvent)
{ /* Aktionen beim Aktivieren des Fensters */ }
void WindowClosed (WindowEvent) { ... }
void windowClosing (WindowEvent) { System.exit(0); }
...
void windowOpened (WindowEvent) { ... }
}
MyWindowListener mwl = new MyWindowListener();
f.addWindowListener(mwl);
Grundlagen der Programmierung 2 im SS 2008
// z.B. für "meinen" MyFrame f
54
Programmiertechnik für Listener 3
Universität Paderborn
Prof. Dr. Stefan Böttcher
Variante 2: Zu jedem Ereignistyp XXXEvent gibt es eine abstrakte
Klasse XXXAdapter mit leeren Methodenimplementierungen:
public abstract class WindowAdapter implements
WindowListener {
public void windowActivated (WindowEvent){}
public void WindowClosed (WindowEvent)
{}
...
public void windowOpened (WindowEvent)
{}
}
Reaktion auf nur wenige Methodenaufrufe des Interface:
Deklaration einer Unterklasse von XXXAdapter und
Überschreibung der benötigten Adapter-Methoden:
f.addWindowListener (
new WindowAdapter(){
public void windowClosing (WindowEvent e) {System.exit(0);}
}
);
Grundlagen der Programmierung 2 im SS 2008
55
Texteingabe
Universität Paderborn
Prof. Dr. Stefan Böttcher
JTextField: einzeiliger, edierbarer Text
Ereignisse: ActionEvent (wie bei Button) ausgelöst bei Return
einige Methoden (aus der Oberklasse TextComponent):
String getText ()
Textinhalt liefern
void setText (String v)
Textinhalt setzen
void setEditable (boolean e)
Editierbarkeit festlegen
boolean isEditable ()
Editierbarkeit überprüfen
void select (int start, int end)
Definition des selektierten Teilstring
void selectAll ()
Selektion des gesamten Textes
Nach Return: Aufruf der Methode actionPerformed()
Darin: Zugriff auf die Ereignisquelle mit getSource()
Herausholen des vom Benutzer eingegebenen Textes mit getText()
Grundlagen der Programmierung 2 im SS 2008
56
Texteingabe - Listener
Universität Paderborn
Prof. Dr. Stefan Böttcher
Beispiel: ActionListener für JTextField:
new ActionListener () {
public void actionPerformed (ActionEvent e)
{ str = (JTextField)(e.getSource()).getText();
}
}
Beispielprogramm:
Benutzer tippt Namen ein
Abschluss mit RETURN
Ausgeben des Namens
Beenden der Editierbarkeit
Grundlagen der Programmierung 2 im SS 2008
RETURN
57
Texteingabe - Beispielanwendung
Universität Paderborn
Prof. Dr. Stefan Böttcher
JFrame mit JTextfield
class Namenseingabe extends JFrame implements ActionListener {
JTextField tNamenseingabe = new JTextField("(unbekannt)");
JLabel l1 = new JLabel ("Geben Sie Ihren Namen ein!");
JLabel l2 = new JLabel ("Ich weiß nicht wie Sie heißen.");
public void actionPerformed(ActionEvent e) {
l2.setText("Sie heißen also
"+((JTextField)e.getSource()).getText() );
tNamenseingabe.setEditable(false);
}
Namenseingabe() {
getContentPane().setLayout(new FlowLayout());
getContentPane().add(l1);
getContentPane().add(tNamenseingabe);
getContentPane().add(l2);
tNamenseingabe.addActionListener(this);
tNamenseingabe.selectAll(); //Selektiert Eingabe am Anfang
setSize(200, 110);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
TextFeld.java
}
}
Grundlagen der Programmierung 2 im SS 2008
58
Eingabe von Zahlen
Universität Paderborn
Prof. Dr. Stefan Böttcher
Eingelesenen Text in eine Zahl konvertieren,
Ausnahme abfangen:
try {
n = new Integer(str).intValue();
} catch (NumberFormatException e) { ... }
try
{
n = Integer.parseInt (str);
} catch (NumberFormatException e) { ... }
Programmvariante: Eingabe des Alters, Berechnung des
Geburtsjahres, Abfangen von Eingabefehlern (keine Zahl,
negatives Alter)
Grundlagen der Programmierung 2 im SS 2008
59
Beispiel: Zahleneingabe
Universität Paderborn
Prof. Dr. Stefan Böttcher
public void actionPerformed(ActionEvent e) {
int iDiesJahr = 2008;
String s = ((JTextField)e.getSource()).getText();
int gebJahr = 0;
boolean fehler = false;
try
{ gebJahr = iDiesJahr - Integer.parseInt(s); }
catch(NumberFormatException n) { fehler = true; }
if (fehler)
l2.setText("Sie sollten eine Zahl eingeben.");
else if (gebJahr > iDiesJahr)
l2.setText("Sie sollten eine nicht-negative Zahl eingeben.");
else
l2.setText("Ihr Geburtsjahr ist "+gebJahr+".");
tAlterseingabe.selectAll();
}
TextFeld2.java
Grundlagen der Programmierung 2 im SS 2008
60
Beispiel: Zahleneingabe
Universität Paderborn
Prof. Dr. Stefan Böttcher
Variante: aktuelles Jahr durch Systemzeit bestimmen
new Date().toString()
liefert Datum, Uhrzeit, Zeitzone.
Wed Apr 3 12:34:00 CEST 2008
Feste Positionen der einzelnen Angaben!
Jahreszahlermittelung durch
(new Date().toString()).substring(25)
Berechnung des aktuellen Jahres mit
int iDiesJahr = Integer.parseInt(
(new Date().toString()).substring(25) );
Grundlagen der Programmierung 2 im SS 2008
61
JTextArea
Universität Paderborn
Prof. Dr. Stefan Böttcher
Für mehrzeiligen Text
Kein ActionListener,
keine Funktion actionPerformed
Return in der JTextArea beendet
nicht die Eingabe
„Fertig-Button“ außerhalb der
JTextArea beendet Eingabe
Grundlagen der Programmierung 2 im SS 2008
62
Unterschiede JTextArea JTextField
Universität Paderborn
Prof. Dr. Stefan Böttcher
Angabe der Zeilen und Spalten:
JTextArea tLebenseingabe =
new JTextArea("(Eingabe \nLebenslauf)", 20, 20);
Lesen des eingegebenen Textes mittels Button-Event
lebenslauf = tLebenseingabe.getText();
Löschen des eingegebenen Textes duch
TextArea.java
tLebenseingabe.setText("");
Setzen des Focus (Ziel für Tastatureingabe) auf das JTextField
tLebenseingabe.requestFocusInWindow();
Definition des Textumbruchsverhaltens bei der Eingabe
tLebenseingabe.setLineWrap(true);
tLebenseingabe.setWrapStyleWord(true);
Grundlagen der Programmierung 2 im SS 2008
63
Scrollbars für JTextArea
Universität Paderborn
Prof. Dr. Stefan Böttcher
Verwalten der Darstellung der JTextArea durch
Container JScrollPane
JScrollPane scp = new JScrollPane(tLebenseingabe);
getContentPane().add(scp);
TextArea2.java
Grundlagen der Programmierung 2 im SS 2008
64
JComboBox
Universität Paderborn
Prof. Dr. Stefan Böttcher
Alternativen können der JComboBox als String-Array im
Konstruktor übergeben werden:
String [] name = { "A", "B", "C" };
JComboBox cAuswahl = new JComboBox(name);
ComboBoxTest.java
Grundlagen der Programmierung 2 im SS 2008
65
JComboBox Events
Universität Paderborn
Prof. Dr. Stefan Böttcher
Auswahl-Komponenten (JComboBox) lösen ActionEvents aus sobald
ein Element ausgewählt wird.
Mittels actionPerformed kann ein ActionListener darauf reagieren:
cAuswahl.addActionListener(this);
public void actionPerformed(ActionEvent e)
{
lErgebnis.setText("Sie nennen Ihr Baby also " +
(String)cAuswahl.getSelectedItem()+".");
}
Zugriff auf das gewählte Item über den „Index“:
cAuswahl.getSelectedIndex()
Bei n Alternativen: Wert zwischen 0 und n-1
Ein ItemListener kann unmittelbar auf Selektionsänderung reagieren –
nicht erst nach endgültigem Auswählen
Grundlagen der Programmierung 2 im SS 2008
66
JComboBox Items
Universität Paderborn
Prof. Dr. Stefan Böttcher
Items können dynamisch hinzugefügt
und entfernt werden:
cAuswahl.addItem("D");
cAuswahl.removeItem("A");
Auswahlbox kann "editierbar" sein
Freie Eingabe von Texten, nicht nur Auswahl aus
vordefinierten Items:
cAuswahl.setEditable(true);
Übernahme der Eingabe mit getSelectedItem()
getSelectedItemIndex() wird dann negativ!
Grundlagen der Programmierung 2 im SS 2008
67
Menüs
Universität Paderborn
Prof. Dr. Stefan Böttcher
JMenuBar – Leiste am Fensterrand,
welche die Menüs aufnimmt
JMenu – Einzelnes Menu unter einer
Eintragung in der MenuBar
JMenuItem – Menüpunkt (MenuItem),
der eine Aktion auslöst
ActionListener – MenuItems lösen bei Anwahl ActionEvent aus,
Items können mit „ActionCommand“ String identifiziert werden
Zuweisung von Tastatur-ShortCuts möglich
MenuItems können durch setEnabled(false) deaktiviert
(„ausgegraut“) werden, durch setEnabled(true) aktiviert werden
Menuvariante JPopupMenu erscheint „über“ Objekten
Hinzufügen von JMenu als JMenuItem führt zu geschachtelten
Menüs
Grundlagen der Programmierung 2 im SS 2008
68
Menüs - Programmschema
Universität Paderborn
Prof. Dr. Stefan Böttcher
class MyFrame extends JFrame implements ActionListener {
private JMenuBar menuBar;
private JMenu einMenu;
private JMenuItem item1, item2, item3;
...
public MyFrame(...) {
//Konstruktor
menuBar = new JMenuBar();
//Erzeugen der Menüleiste
einMenu = new JMenu("Darstellung");
//Erzeugen eines Menüs
item1 = new JMenuItem("Item1");
//Erzeugen eines Items “Item1”
item1.setActionCommand("item1-text");
//String für Action
item1.addActionListener(this);
//Anbinden des ActionListeners
...
//analog mit item2, item3, ...
einMenu.add(item1);
//Einfügen ins Menu
einMenu.add(item2);
einMenu.addSeparator();
//Einfügen eines Trennstrichs
...
menuBar.add(einMenu);
// Einbinden des Menus in die Menubar
setJMenuBar(menuBar);
// Anbinden der Menüleiste in den Frame
...
} //Ende des Konstruktors
MenuTest.java
Grundlagen der Programmierung 2 im SS 2008
69
Menüs - Aktionen
Universität Paderborn
Prof. Dr. Stefan Böttcher
public void actionPerformed(ActionEvent e){
//Bei Menuitem Anwahl
String c = e.getActionCommand();
//Holen des ActionCommand Strings
if (c.equals("item1-text")) {
...
//Aktionen des Menuitems 1
}
else { ... }
//Abfrage weiterer ActionCommand-Strings
}
A “verbinden” mit B: A → B
JFrame
JMenuBar
JMenu
JMenuItem
JMenuItem
...
JMenuBar → JFrame: setJMenuBar(JMenuBar)
JMenu → JMenuBar: JMenuBar.add(JMenu)
JMenuItem → JMenu: JMenu.add(JMenuItem)
JMenuItem → ActionCommand:
JMenuItem.setActionCommand(ActionCommand)
JMenuItem → ActionListener:
JMenuItem.addActionListener(...);
Jmenu ...
Grundlagen der Programmierung 2 im SS 2008
70
Menüs - Beispielprogramm
Universität Paderborn
Prof. Dr. Stefan Böttcher
Datei
Neu
Öffnen
Schliessen
Ende
Bearbeiten
Kopieren
Ausschneiden
Einfügen
Suchen
Hilfe
Über
Index
Grundlagen der Programmierung 2 im SS 2008
71
Untermenüs
Universität Paderborn
Prof. Dr. Stefan Böttcher
Einbinden von Menus als Items führt zu Untermenüs, etwa
...
Hilfe
Über
Index
Identifier
Funktionen
Konstanten
JMenuItem iIndex (Item Index)
ersetzen durch JMenu mIndex (Menü Index)
dieses konventionell aufbauen und mit
mHilfe.add(mIndex) hinzufügen.
MenuTest2.java
Grundlagen der Programmierung 2 im SS 2008
72
Zusammenfassung
Universität Paderborn
Prof. Dr. Stefan Böttcher
Dialogfenster
Aktionen an Buttons anbinden
ActionListener
ActionCommand
Programmiertechnik für Listener
Anonyme Klassen
Texteingabefelder
ComboBoxen und deren Events
Menüs und Untermenüs
Grundlagen der Programmierung 2 im SS 2008
73