Java Standard: Grafische Oberflächen mit AWT
Das Abstract Window Toolkit [AWT] ist eine API zum Entwickeln quasi-plattformunabhängiger grafischer Oberflächen mit Java. Diese "Plattformunabhängigkeit" wurde erreicht, indem komplexere Oberflächenelemente wie Bäume und Tabellen, welche nicht auf allen Betriebssystemen vorhanden sind, nicht in das AWT aufgenommen wurden. Diese Beschränkungen können Sie umgehen, indem Sie die seit Java 1.2 im J2SE enthaltenen Swing Komponenten verwenden.
Für die Entwickler von Applets ist das AWT vielfach jedoch noch der kleinste gemeinsame Nenner, da alle heute gängigen Browser lediglich den Java 1.1 Standard beherrschen.
Grafische Komponenten
[Bearbeiten]AWT-Komponenten sind entweder im Package java.awt
oder in den dazugehörenden Subpackages zu finden.
Fenster mit Rahmen
[Bearbeiten]Die Klasse Window
repräsentiert ein Fenster ohne Rahmen und ohne Menüleiste. Frame
ist eine Subklasse von Window
und beinhaltet Fensterrahmen und die Möglichkeit eine Menüleiste einzubinden.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { public TestFrame () { setTitle("Ein reines, unbeflecktes Frame"); // Fenstertitel setzen setSize(400,100); // Fenstergröße einstellen addWindowListener(new TestWindowListener()); // EventListener für das Fenster hinzufügen // (notwendig, damit das Fenster geschlossen werden kann) setVisible(true); // Fenster (inkl. Inhalt) sichtbar machen } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); // Fenster "killen" System.exit(0); // VM "killen" } } public static void main (String args[]) { new TestFrame (); } }
Menüs
[Bearbeiten]Für die Erstellung von Menüs sind folgende wesentliche Java-AWT-Klassen notwendig:
MenuBar
- die Menüleiste, wie sie auch in Ihrem Browser zu finden istMenu
- ist ein Menü oder Untermenü (z.B. "Datei")MenuItem
- ist ein Menüeintrag (z.B. "Neues Fenster")
Um Untermenüs zu erzeugen, fügen Sie das Untermenü dem Menü mit der Methode add (MenuItem)
hinzu.
Beispiel:
import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class MenuSample { public MenuSample () { Frame f = new Frame ("Menübeispiel"); f.addWindowListener(new WindowAdapter () { public void windowClosing (final WindowEvent e) { System.exit(0); } }); f.setMenuBar(this.getMenubar ()); f.setSize(400,100); f.setVisible(true); } protected MenuBar getMenubar () { // Menüleiste anlegen MenuBar menueLeiste = new MenuBar (); // Ein Menü anlegen Menu datei = new Menu ("Datei"); // Einen Menüeintrag anlegen MenuItem oeffnen = new MenuItem ("Öffnen"); // Den Eintrag dem Menü hinzufügen datei.add (oeffnen); // Das Menü der Leiste hinzufügen menueLeiste.add(datei); // Noch ein Menü anlegen Menu extra = new Menu ("Extras"); // ... und noch ein Menü Menu schriftart = new Menu ("Schriftart"); //...das Menü dem Extramenü als Untermenü hinzufügen extra.add(schriftart); // Das Untermenü mit Einträgen füllen schriftart.add("Sans"); schriftart.add("Sans Serif"); schriftart.addSeparator(); schriftart.add("Courier"); // Das Extramenü der Leiste hinzufügen menueLeiste.add(extra); return menueLeiste; } public static void main (String[] args) { MenuSample menusample = new MenuSample (); } }
Schaltflächen
[Bearbeiten]AWT-Schaltflächen sind durch die Klasse Button
zu erstellen.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { Button button = new Button("Schaltfläche"); public TestFrame () { setTitle("Schaltflächenbeispiel"); addWindowListener(new TestWindowListener()); button.setForeground(Color.RED); // Vordergrundfarbe auf "rot" setzen button.setBackground(Color.WHITE); // Hintergrundfarbe auf "weiß" setzen button.addActionListener(new TestActionListener()); // EventListener für Schaltfläche hinzufügen add(button); // Schaltfläche zum Fenster hinzufügen pack(); // Fenstergröße auf die benötigte Größe // "zusammenpacken" setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } class TestActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Schaltfläche wurde gedrückt"); } } public static void main (String args[]) { new TestFrame (); } }
Beschriftungen
[Bearbeiten]Beschriftungen können Sie mit Label
generieren. Positionieren können Sie die Beschriftungen über die Methode void setAlignment(int alignment)
mit den Konstanten
Label.LEFT
Label.CENTER
Label.RIGHT
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { Label label = new Label("Beschriftung"); public TestFrame () { setTitle("Beschriftungsbeispiel"); addWindowListener(new TestWindowListener()); label.setAlignment(Label.CENTER); // Label zentrieren add(label); // Label zum Fenster hinzufügen setSize(300,150); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Texteingabefelder
[Bearbeiten]Einzeilig
[Bearbeiten]Einzeilige Texteingabefelder lassen sich mit der Klasse TextField
erstellen. Den Inhalt eines Texteingabefeldes können Sie mittels der Methode String getText()
auslesen. Zum Zwecke der Erstellung von Passworteingabefeldern lässt sich die Anzeige des Eingabetextes durch die Methode void setEchoChar(char c)
maskieren.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { public TestFrame () { setTitle("TextEntry-Beispiel"); addWindowListener(new TestWindowListener()); add(new TextField("Hallo")); // Texteingabefeld mit einer Textvorgabe pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Mehrzeilig
[Bearbeiten]Mehrzeilige Texteingabefelder können Sie mit der Klasse TextArea
erstellen. Auch diese Klasse implementiert bzw. erbt eine Vielzahl von Methoden durch welche sie das Erscheinungsbild anpassen und Text setzen oder abfragen können.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { public TestFrame () { setTitle("TextArea-Beispiel"); addWindowListener(new TestWindowListener()); /* 5 Zeilen hoch, 30 Spalten breit */ add(new TextArea("Hallo Welt!\nWo sind deine vielgerühmten Genies?", 5,30)); pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Kontrollkästchen (Checkboxes) und Optionsfelder (Radiobuttons)
[Bearbeiten]Zur Erstellung von Kontrollkästchen dient die Klasse Checkbox
. Mittels boolean getState()
ist der Zustand einer Checkbox abfragbar. Durch eine Zusammenfassung mehrerer Checkboxes in einer CheckboxGroup
sind auch Radiobuttons realisierbar.
Beispiele:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { public TestFrame () { setTitle("Checkbox-Beispiel"); addWindowListener(new TestWindowListener()); add(new Checkbox("Farbdarstellung", true)); pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Aufklappbare Auswahlliste (Choice)
[Bearbeiten]Ein Choice ist eine ausklappbarer Auswahlliste. Die momentane aktive Auswahl wird auch im eingeklappten Zustand angezeigt. Die Funktion eines Choice ist vergleichbar mit einer Gruppe von Radiobuttons. Durch die Methode void add(String item)
lassen sich Strings in die Auswahlliste eingefügen. Die momentan gewählte Option lässt sich durch die Methode int getSelectedIndex()
oder String getSelectedItem()
abfragen.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { Choice choice = new Choice(); public TestFrame () { setTitle("Choice-Beispiel"); addWindowListener(new TestWindowListener()); choice.add("Farbdarstellung"); choice.add("Graustufen"); choice.add("B/W"); add(choice); pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Auswahlliste (List)
[Bearbeiten]Eine weitere Möglichkeit zur Selektion verschiedener Optionswerte bietet die List
(nicht zu verwechseln mit dem Kollektions-Interface java.util.List
). Bei einer List
ist im Gegensatz zum/zur Choice
standardmäßig keine Vorauswahl getroffen. Ein Listeneintrag kann aber mittels der Methode void select(int index)
vorausgewählt werden. In einer Auswahlliste können mehrere Einträge ausgewählt werden (Multiselektion), wenn ein derartiges Verhalten vom Programmierer über den List
-Konstruktor oder die Methode void setMultipleMode(boolean b)
vorgesehen wird.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { List list = new List(); public TestFrame () { setTitle("List-Beispiel"); addWindowListener(new TestWindowListener()); list.add("Farbdarstellung"); list.add("Graustufen"); list.add("B/W"); add(list); pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Panel
[Bearbeiten]Ein Panel ist eine simple Containerklasse zur Aufnahme anderer AWT-Komponenten. Besonders im Zusammenhang mit komplexeren AWT-GUI-Layouts ist der Einsatz der Klasse Panel
im Zusammenwirken mit Layout-Managern unverzichtbar. Auch als "Zeichenfläche" eignet sich ein Panel. Panel
-Konstruktoren sind Panel()
und Panel(LayoutManager layout)
. AWT-Komponenten werden mit diversen add
-Methoden zu einem Panel hinzugefügt. Applet
ist eine Panel
-Subklasse.
Beispiel 1:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { Panel panel= new Panel(); public TestFrame () { setTitle("Panel-Beispiel"); addWindowListener(new TestWindowListener()); panel.add(new Button("OK")); panel.add(new Button("Abbrechen")); add(panel); pack(); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Beispiel 2:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { public TestFrame () { setTitle("Panel-Beispiel"); addWindowListener(new TestWindowListener()); add(new DrawingPanel()); setSize(300,100); setVisible(true); } class DrawingPanel extends Panel { public void paint(Graphics g) { g.setColor(Color.GREEN); g.fillRect(20, 10, 50, 50); g.setColor(Color.RED); g.fillOval(100, 10, 50, 50); g.setColor(Color.BLUE); g.drawString("Hallo Welt!", 200, 40); g.setColor(Color.WHITE); g.drawRect(180, 10, 100, 50); } } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Canvas
[Bearbeiten]Ein Canvas
ist eine leere AWT-Komponente ohne Grundfunktionalität. Ein Canvas kann wie ein Panel als reine "Zeichenfläche" verwendet werden oder als Grundlage für die Erstellung eigener AWT-Komponenten dienen.
ScrollPane
[Bearbeiten]Eine ScrollPane ist ein Container zur Aufnahme einer AWT-Komponente. Eine ScrollPane bietet vertikale und horizontale Scrollbars. Wann und wie diese Scrollbars erscheinen, kann vom Programmierer festgelegt werden (SCROLLBARS_ALWAYS
, SCROLLBARS_AS_NEEDED
, SCROLLBARS_NEVER
). Des Weiteren kann auch das Verhalten der Scrollbars beinflusst werden (z.B. ob Scrolling auch mit dem Mausrad möglich sein soll oder die initiale Scrollposition).
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { ScrollPane scroll = new ScrollPane(); Panel panel = new Panel(); public TestFrame () { setTitle("ScrollPane-Beispiel"); addWindowListener(new TestWindowListener()); for(int i=1; i<=10; i++) { panel.add(new Label("Beschriftung " + i)); } scroll.add(panel); add(scroll); setSize(300,100); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Dialoge
[Bearbeiten]Dialog
ist eine Window
-Subklasse. Dialoge können modal oder nichtmodal sein.
Ein Dialog wird immer mit einem Konstruktor erstellt, dem als erster Parameter ein Frame
, ein anderer Dialog
oder null
übergeben wird. Sinnvollerweise wird die Klasse Dialog
für Benutzereingaben, Meldungsfenster, About-Dialoge oder dergleichen genutzt.
Dateiauswahldialog
[Bearbeiten]Mit der Klasse FileDialog
lässt sich sehr einfach ein modaler Dateiauswahldialog generieren.
Beispiel:
import java.awt.*; import java.awt.event.*; public class TestFrame extends Frame { Button button = new Button("Dateidialog aufrufen"); FileDialog fd; public TestFrame () { setTitle("FileDialog-Beispiel"); addWindowListener(new TestWindowListener()); fd = new FileDialog(this, "Dateidialog"); add(button); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fd.setVisible(true); } }); setSize(300,100); setVisible(true); } class TestWindowListener extends WindowAdapter { public void windowClosing(WindowEvent e) { e.getWindow().dispose(); System.exit(0); } } public static void main (String args[]) { new TestFrame (); } }
Layoutmanager
[Bearbeiten]Die Layoutmanager für AWT und Swing werden in dem Kapitel Swing: Layoutmanager behandelt.
FlowLayout
[Bearbeiten]Beispiel zum FlowLayout
:
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends Frame
{
public TestFrame ()
{
setTitle("FlowLayout-Beispiel");
addWindowListener(new TestWindowListener());
setLayout(new FlowLayout()); // FlowLayout setzen
for(int i=1; i<=10; i++)
{
add(new Label("Beschriftung" + i));
}
setSize(300,150);
setVisible(true);
}
class TestWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
public static void main (String args[])
{
new TestFrame ();
}
}
BorderLayout
[Bearbeiten]Dieses Layout platziert Komponenten in 5 möglichen Bereichen: oben, unten, links, rechts, zentriert.
Beispiel zum BorderLayout
:
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends Frame
{
public TestFrame ()
{
setTitle("BorderLayout-Beispiel");
addWindowListener(new TestWindowListener());
setLayout(new BorderLayout()); // BorderLayout setzen
add(new Label("Centertruder", Label.CENTER), BorderLayout.CENTER); // CENTER
add(new Label("Westruder", Label.CENTER), BorderLayout.WEST); // WEST
add(new Label("Eastruder", Label.CENTER), BorderLayout.EAST); // EAST
add(new Label("Northtruder", Label.CENTER), BorderLayout.NORTH); // NORTH
add(new Label("Southtruder", Label.CENTER), BorderLayout.SOUTH); // SOUTH
setSize(300,150);
setVisible(true);
}
class TestWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
public static void main (String args[])
{
new TestFrame ();
}
}
GridLayout
[Bearbeiten]Beispiel zum GridLayout
:
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends Frame
{
public TestFrame ()
{
setTitle("GridLayout-Beispiel");
addWindowListener(new TestWindowListener());
setLayout(new GridLayout(4,3)); // GridLayout setzen
for (int i=1; i<=10; i++)
{
add(new Label("Beschriftung" + i));
}
setSize(300,150);
setVisible(true);
}
class TestWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
public static void main (String args[])
{
new TestFrame ();
}
}
GridBagLayout
[Bearbeiten]Das GridBagLayout ist ein komplexer LayoutManager2
[1], mit welchem eine Menge an Möglichkeiten geboten werden. Die eigentliche Ausrichtigung der Komponenten erfolgt über das GridBagConstraints
Objekt, welches beim Hinzufügen zum Container anzugeben ist.
Beispiel zum GridBagLayout
:
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends Frame
{
GridBagLayout grid = new GridBagLayout();
GridBagConstraints straints = new GridBagConstraints();
Button button;
public TestFrame ()
{
setTitle("GridBagLayout-Beispiel");
setLayout(grid); // GridBagLayout setzen
addWindowListener(new TestWindowListener());
straints.gridx = straints.gridy = 0;
straints.gridheight = straints.gridwidth = 1;
straints.fill = GridBagConstraints.BOTH;
button = new Button("Hallo");
grid.setConstraints(button, straints);
add(button);
straints.gridy = 1;
button = new Button("du");
grid.setConstraints(button, straints);
add(button);
straints.gridx = 1;
straints.gridy = 0;
straints.gridheight=2;
button = new Button("Welt!");
grid.setConstraints(button, straints);
add(button);
straints.gridx = 0;
straints.gridy = 2;
straints.gridheight = 1;
straints.gridwidth = 2;
button = new Button("Was ist ein GridBag?");
grid.setConstraints(button, straints);
add(button);
pack();
setVisible(true);
}
class TestWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
public static void main (String args[])
{
new TestFrame ();
}
}
NullLayout
[Bearbeiten]Ein NullLayout ist im eigentlichen Sinne kein Layout. Hierbei können die Elemente frei, mittels Positionsangaben, auf der Oberfläche positioniert werden.
Beispiel zum "Null-Layout":
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends Frame
{
Label label;
public TestFrame ()
{
setTitle("Null-Layout-Beispiel");
addWindowListener(new TestWindowListener());
setLayout(null); // "Null-Layout" setzen
for(int i=1; i<=5; i++)
{
label = new Label("Beschreibung" + i);
label.setBounds(10+i*20, 20+i*(25-2*i), 100, 15); // x, y, breite, höhe
add(label);
}
setSize(300,150);
setVisible(true);
}
class TestWindowListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
}
public static void main (String args[])
{
new TestFrame ();
}
}
Ereignisse
[Bearbeiten]Damit AWT-Komponenten nicht nur mäßig schön am Bildschirm erstrahlen, sondern auch Funktionalität aufweisen, müssen sie auf Benutzeraktionen reagieren können.
Das Ereignis-Delegations-Modell (Event Delegation Model, Delegation Based Event Handling) ab Java 1.1 basiert auf dem Prinzip des Beobachter-Entwurfsmusters (Observer Pattern).
Was ein Beobachter-Entwurfsmusters ist, kann folgenden Quellen entnommen werden:
- Beobachter (Entwurfsmuster)
- In diesem Buch in dem Kapitel Muster Observer
- Wikibooks: (Entwurfs) Muster, Kapitel Muster: Observer
Jede AWT-Komponente kann Ereignisquelle sein. Jedes Objekt kann Ereignisempfänger sein. Damit ein Objekt Ereignisse empfangen kann, muss es bei einer Ereignisquelle als Ereignisempfänger registriert werden.
AWT-Ereignisse
[Bearbeiten]AWT-Komponenten, als Ereignisquellen, reagieren auf externe Aktivitäten (z.B. Tastendruck, Mausbewegung, Mausklick) mit der Konstruktion von Ereignis-Objekten. Je nach Typ der Aktivität wird ein geeignetes Objekt erzeugt. Nachfolgendes Bild zeigt ein Klassendiagramm (basierend auf der Java 2 SE 5.0-API-Dokumentation), aus dem diese Ereignis-Objekte generiert werden. Alle möglichen AWT-Ereignisse sind Subklassen der abstrakten Klasse AWTEvent
. Auch zusätzliche Swing-Events werden von dieser Klasse abgeleitet.
Ereignisempfänger (EventListener)
[Bearbeiten]Als Ereignisempfänger bietet das Package java.awt.event
verschiedene EventListener
-Interfaces. Diese Ereignisempfänger werden bei der das Ereignis auslösenden AWT-Komponente registriert. Zu diesem Zweck besitzen die AWT-Komponenten geeignete add<X>Listener
-Methoden. Für manche Listener-Interfaces existieren Adapter-Klassen. Diese implementieren das entsprechende Interface mit leeren Funktionsrümpfen.
Beispiel:
Schaltflächen lösen beim Anklicken ein ActionEvent
aus. Der Ereignisempfänger ist vom Typ
ActionListener
. Die Methode zum Registrieren dieses Ereignisempfänger heißt void
addActionListener(ActionListener l)
. Das entsprechende Implementierungsbeispiel wurde bereits im Absatz Schaltflächen gezeigt.
Ereignisempfänger (EventAdapter)
[Bearbeiten]Die Ereignisempfänger (EventListener)
sind Interfaces. Dem großen Vorteil, die Problematik der nicht vorhandenen Mehrfachvererbung umgangen zu haben, steht somit (leider) der erhöhte Implementierungsaufwand entgegen. Um dieses Ärgernis zu Umgehen hat Sun netterweise sogenannte Adapterklassen bereitgestellt. Diese enthalten eine leere Defaultimplementation aller zu überschreibenen Methoden (siehe NullPattern). Lediglich für den ActionListener
gibt es keinen Adapter - nunja dort gibt es auch nur eine Methode zu überschreiben.