Benutzereingaben mit Swing einlesen
Wie schon behandelt, kann zu einem Fenster eine Textfläche (ein Textfeld) der Klasse "javax.swing.JTextField" hinzugefügt werden.
Durch die Nachricht "setText( java.lang.String t )" wird der Text des Textfeldes auf den Text "t" gesetzt.
Die entscheidende Neuerung an dem folgenden Programm ist der Aufruf »Main.this.text.addActionListener( this );«: Dadurch wird dem Textfeld-Objekt eine Referenz auf das Main -Objekt übergeben. Das Textfeld-Objekt merkt sich dann diese Referenz auf das Main -Objekts. So kann das Textfeld-Objekt später Nachrichten an das Main -Objekt schicken. Das Textfeld-Objekt versendet immer dann eine Nachricht an das Main -Objekt, wenn der Benutzer etwas eingegeben hat (bei Tippen der Eingabetaste). Das Main -Objekt kann dann auf solch eine Eingabe reagieren.
Das Textfeld ruft bei einer Benutzereingabe die Main-Methode »actionPerformed« auf. Damit der Compiler auf prüfen kann, daß diese Methode in der Klasse »Main« überhaupt implementiert wurde, muß die Klasse »Main« dazu die Schnittstelle »java.awt.event.ActionListener« implementieren.
Aufrufe durch Swing -Objekte bei bestimmten Ereignissen, wie etwa der Aufruf von »actionPerformed«, finden immer auf dem Prozessor »AWT-EventQueue-0« statt. Dadurch läuft die aufgerufene Methode »actionPerformed« dann ebenfalls auf dem Prozessor »AWT-EventQueue-0«, es ist in diesem Fall also nicht nötig, erst »invokeLater« zu verwenden, um auf den »AWT-EventQueue-0« zu gelangen.
Main.java
final class Main implements
java.awt.event.ActionListener,
java.lang.Runnable
{
public final javax.swing.JTextField text
= new javax.swing.JTextField( "Müßiggang" );
/* java.awt.event.ActionListener-Rückrufmethode für Window.this.text */
public void actionPerformed( final java.awt.event.ActionEvent event )
{ Main.this.text.setText( Main.this.text.getText().toUpperCase() ); }
/* java.lang.Runnable-Rückrufmethode für javax.swing.SwingUtilities.invokeLater */
public void run()
{ final javax.swing.JFrame frame
= new javax.swing.JFrame( "Text in Großbuchstaben wandeln." );
Main.this.text.addActionListener( this );
frame.add( Main.this.text, java.awt.BorderLayout.CENTER );
frame.setDefaultCloseOperation( javax.swing.JFrame.EXIT_ON_CLOSE );
frame.pack(); frame.setVisible( true ); }
public static void main( final java.lang.String[] args )
{ javax.swing.SwingUtilities.invokeLater( new Main() ); }}
Man beachte: Alle Variablen, Felder und Parameter sind final.
[UML collaboration diagram]
run
.----------------. -------------> .-------.
| SwingUtilities |---------------------------| :Main |
| | | ----- |
'----------------' '-------'
actionPerformed(event) |
.----------------. -------------> |
| :JTextField |-------------------------------'
| ----------- |
'----------------'- Oberfläche
.----------------.
| Text in Gro... |
|----------------| Eingabetaste .----------------.
||Muessiggang ----------------------->| MUESSIGGANG |
'----------------' '----------------'- Verdrahtung
.----------.
| Textfeld |
'----------'
|
Main-Objekt v
.-------------------------------------.
| |
| actionPerformed |
| |
'-------------------------------------'Ablauf
Thread Methode
main: main ->| (einmalig)
.
Existenz | EDT: run ->| (einmalig)
des Main- |
Objekts | EDT: actionPerformed ->| (beliebig oft)
|
| close -> EXIT (einmalig)
|
V
UML-Sequenzdiagramme
- Die Zeit verläuft von oben nach unten.
- „Entität“ ist irgendetwas (als Oberbegriff zu Klasse, Methode und Mensch)
- Fortsetzung der Existenz eines Menschen »user« [UML sequence diagram]
user
|
|
|- Anfang oder Fortsetzung der Existenz einer Klasse »Beta« [UML sequence diagram]
Beta
|
|
|- Anfang der Existenz eines Objekts der Klasse Klasse »Beta« [UML sequence diagram]
:Beta
|
|
|- Ende der Existenz einer Entität [UML sequence diagram]
|
|
|
X- Erzeugung eines neuen Objekts einer Klasse »Beta« durch eine Entität »x« [UML sequence diagram]
x
|
|
| new
|----------------------------->:Beta
| |
| |
| |- Eine Entität wird aktiv (d.h. eine ihrer Methoden beginnt zu laufen) [UML sequence diagram]
|
|
|
.-.
| |
| |
| |- Die Aktivität einer Entität endet (d.h. keine ihrer Methoden läuft) [UML sequence diagram]
| |
| |
| |
'-'
|
|
|- Senden einer Nachricht »message« von einer Entität (links) an eine andere Entität (rechts) [UML sequence diagram]
| |
| |
| message |
|----------------------------->.-.
| | |
| | |
| | |- Senden einer Nachricht »message« von einer Entität (links) an eine andere Entität (rechts) [UML sequence diagram]
| |
| |
| message |
|----------------------------->.-.
| | |
| | |
| | |
user
|
|
Main Swing |
| | |
.-. | new |
| |------------------------->:Main |
| | | | |
| | .-. | |
| |-------------->| | run | |
'-' invokeLater | |-------->.-. |
| | | | | new |
X | | | |----------------------> :TextField |
| | | | | |
| | | | addActionListener(this) | |
| | | |-------------------------->.-. |
| | | | | | |
| |<--------'-' '-' |
'-' | | |
| | | Enter .-.
| | .-.<--------| |
| | actionPerformed | | '-'
| .-.<--------------------------| | |
| | | '-' |
| | | setText | |
| | |-------------------------->.-. |
| '-' | | |
| | '-' |
| | | |
| | | Enter .-.
| | .-.<--------| |
| | actionPerformed | | '-'
| .-.<--------------------------| | |
| | | '-' |
| | | setText | |
| | |-------------------------->.-. |
| '-' | | |
| | '-' |
| | | |
| [X] | | .-.
.-.<--------------------------------------------------| |
| | | | '-'
'-' | | |
| | | |
| | X |
| X |
X |
|Fenster
.----------------.
| U Tex... _ O X |
|----------------|
|.--------------.|
|| Müßiggang ||
|'--------------'|
'----------------'
Das Main -Objekt existiert weiter, auch wenn der Main -Prozessor das Programm schon vollständig abgearbeitet hat ist. Zwischen verschiedenen Aufrufen von actionPerformed kann eine längere Pause sein, aber das Main -Objekt existiert weiter und alle Feldwerte bleiben über die Aufrufe von »run« und »actionPerformed« hinweg erhalten.
Die Werte von Feldern eines Objekts bleiben über mehrere Aufrufe von Methoden dieses Objekts hinweg erhalten, solange dieses Objekt existiert.
Übungsfrage
- Wie viele Objekte der Klasse »Main« existieren während der Ausführung des Programms (zumindest zeitweise)?
Übungsfrage
- Warum findet sich die Deklaration des Bezeichners »frame« innerhalb der Methode »run«, die Deklaration des Bezeichners »text« aber außerhalb?
Übungsfrage/Übungsaufgabe
- Was passiert, wenn (unter Windows) versucht wird, das Wort „Müßiggang“ mit »java.lang.System.out.println« in die Konsole zu schreiben?
Übungsaufgabe (leicht)
- Schreiben Sie das Programm so um, daß es in Kleinschreibung wandelt.
Zähler (mittelschwierig)
- Für Verkehrszählungen werden Zähler verwendet, die bei jeder Betätigung weiterzählen. Schreiben Sie ein Programm, das bei jeder Betätigung der Eingabetaste einen Zähler, dessen Wert zunächst gleich 0 ist, um 1 hochzählt und den Wert im Textfeld anzeigt.
- Hinweis: Eventuell ist es bei dieser Aufgabe hilfreich, in den Klassen »java.lang.String« und »java.lang.Integer« nach Methoden zu suchen, die es erlauben, eine Zahl in einen Text oder einen Text in eine Zahl zu wandeln. Da hierfür unter Umständen mehrere Aufrufe kombiniert werden müssen, ist dies nicht ganz einfach.
- Zusatzaufgabe: Wenn der Benutzer im Textfeld eine andere Zahl eingibt, dann soll der Zähler ab dieser Zahl weiterzählen.