Literatur

JFormattedTextField

Die Klasse JFormattedTextField ist eine Erweiterung der Klasse JTextField. Im Gegensatz zum normalen Textfeld wird bei einem JFormattedTextField der eingegebene Text auf eine bestimmte Formatierung überprüft (geparst) und ggf. entsprechend modifiziert.

Ein typisches Einsatzgebiet für diese Klasse ist beispielsweise die Erstellung von Datum-Eingabefeldern. Die Klasse JFormattedTextField führt selbst keine Formatierung durch. Dafür ist eine Instanz von JFormattedTextField.AbstractFormatter zuständig. Diese werden häufig über eine Instanz der Klasse JFormattedTextField.AbstractFormatterFactory ermittelt. So können mehrere Textfelder mit der gleichen Formatierung von nur einer AbstractFormatter-Instanz  behandelt werden.

Neben dem Standardkonstruktor besitzt die Klasse JFormattedTextField fünf weitere Konstruktoren, die wir in folgender Tabelle kurz näher erläutern wollen. 

Konstruktor Kurzbeschreibung
JFormattedTextField (Format format) Hier wird eine JFormattedTextField erzeugt, das man über den Parameter format mit einer Format-Instanz verknüpft. Die Klasse Format selbst ist abstrakt, besitzt aber die Subklassen DateFormat, MessageFormat, NumberFormat, die man verwenden kann. Es können natürlich auch eigene Format-Klassen geschrieben werden, die von Format abgeleitet werden und die abstrakten Methoden implementieren müssen.
JFormattedTextField (JFormattedTextField.AbstractFormatter
formatter)
Dieser Konstruktor erstellt ein JFormattedTextField-Objekt, für das über den Parameter formatter der zuständige AbstractFormatter angegeben wird. Da die Klasse AbstractFormatter abstrakt ist, muss eine nicht abstrakte Kindsklasse wie etwa NumberFormatter oder MaskFormatter bzw. eine selbstgeschriebene abgeleitete Klasse verwendet werden.
JFormattedTextField (JFormattedTextField.AbstractFormatterFactory
factory)
Hier wird ein JFormattedTextField erzeugt, für das die AbstractFormatterFactory im Konstruktor angegeben wird. Da die Klasse abstrakt ist, können auch hier nur eigene abgeleitete Klassen oder bereits existierende Subklassen, wie z.B.  DefaultFormatterFactory verwendet werden.
JFormattedTextField (JFormattedTextField.AbstractFormatterFactory factory, Object currentValue) Hier wird ein Objekt der Klasse JFormattedTextField erzeugt, welches eine Instanz der Klasse AbstractFormatterFactory sowie einen Wert für das Textfeld erwartet.
JFormattedTextField(Object value) Mit diesem Konstruktor wird dem Textfeld ein Wert zugewiesen.

Sollte lediglich der parameterlose Standardkonstruktor verwendet werden, so wird beim Setzen eines Wertes über die setValue-Methode automatisch eine Instanz einer von AbstractFormatter abgeleiteten Klasse mit dem Textfeld verknüpft. Diese wird anhand des Datentyps des gesetzten Wertes ermittelt. Ohne Angaben zur Formatierung bzw. ohne das Setzen eines Wertes verhält sich das JFormattedTextField wie ein normales JTextField.

Die Klasse JFormattedTextField besitzt einige eigene Methoden, von denen wir einige ausgewählte hier näher erläutern möchten.

Methode Kurzbeschreibung
void commitEdit() throws ParseException Diese Methode bezieht den aktuellen Wert über den AbstractFormatter und setzt diesen für das Textfeld.
int getFocusLostBehavior()       Liefert einen Integer-Wert, der angibt, wie sich das JFormattedTextField verhält, wenn es seinen Fokus verliert. Die möglichen Rückgabewerte entsprechen einer der Konstanten, die weiter unten in der Tabelle erläutert werden.
JFormattedTextField.AbstractFormatter getFormatter() Diese Methode gibt die für das Textfeld gesetzte Instanz von AbstractFormatter zurück.
JFormattedTextField.AbstractFormatterFactory getFormatterFactory() Diese Methode gibt die für das Textfeld zuständige Instanz von AbstractFormatterFactory zurück.
Object getValue() Hier wird der letzte gültige Wert zurückgegeben, der der Policy des AbstractFormatters entspricht. Dieser muss nicht mit dem aktuell editierten Wert des Textfeldes übereinstimmen. Soll dieser ermittelt werden, so muss zunächst commitEdit, gefolgt von getValue aufgerufen werden.
boolean isEditValid() Gibt true zurück, wenn der gerade editierte Wert des Textfeldes gültig ist. Dieser Wert wird vom AbstractFormatter verwaltet.
void setFocusLostBehavior(int behavior) Mit dieser Methode wird angegeben, wie das JFormattedTextField reagieren soll, wenn dieses den Fokus verliert. Nähere Informationen finden Sie weiter unten in der Tabelle mit den Konstanten.
void setFormatterFactory
(JFormattedTextField.AbstractFormatterFactory tf)
Setzt die zuständige AbstractFormatterFactory.
void setValue(Object value) Diese Methode setzt einen Wert, der anschließend noch vom AbstractFormatter formatiert wird.

Das JFormattedTextField besitzt mehrere Konstanten, welche beschreiben, was passieren soll, wenn das Textfeld den Fokus verliert, also der Cursor sich nicht mehr in dem Textfeld befindet, weil man z. B. zu einem anderen Bedienelement gewechselt ist und dieses nun den Fokus bekommen hat. Das eingestellte Verhalten kann verändert werden, indem die Konstante, die die gewünschte Reaktion auf den Fokusverlust repräsentiert, der Methode setFocusLostBehavior übergeben wird.

Die verfügbaren Konstanten möchten wir im Folgenden kurz erläutern:

Konstante Beschreibung des Verhalten
JFormattedTextField.REVERT Wird dieser Wert der Methode setFocusLostBehavior übergeben, so wird beim Fokusverlust der aktuelle Textfeld-Eintrag gelöscht und auf den letzten gültigen Wert zurückgesetzt.
JFormattedTextField.COMMIT Beim Fokusverlust wird die Methode commitEdit aufgerufen wird, d.h. das Textfeld übernimmt den formatierten Wert des AbstractFormatters. Wenn commitEdit jedoch eine parseException wirft, bleibt der ungültige Wert dennoch im Textfeld stehen.
JFormattedTextField.COMMIT_OR_REVERT Unterscheidet sich von der Konstante COMMIT darin, dass im Falle einer parseException das Textfeld auf den letzten gültigen Wert zurückgesetzt wird.
JFormattedTextField.PERSIST Bei Verwendung dieser Konstante bleibt der Textfeldeintrag im Falle des Fokusverlustes unverändert.


Nachfolgend finden Sie zum besseren Verständnis nun ein Beispiel:

 
import java.text.NumberFormat;
import java.util.Date;
import javax.swing.*;
 
public class JFormattedTextFieldBeispiel {
    public static void main(String[] args) {
        JFrame meinJFrame = new JFrame();
        meinJFrame.setSize(300, 100);
        meinJFrame.setTitle("JFormattedTextField Beispiel");
        JPanel meinPanel = new JPanel();
 
        // Labels für die Textfelder werden erzeugt
        JLabel labelDatum = new JLabel("Datum");
        JLabel labelBetrag= new JLabel("Betrag");
 
        // Textfeld für die Eingabe eines Datums
        JFormattedTextField tfDatum = new JFormattedTextField(new Date());
 
        // Textfeld für die Eingabe von Zahlen im Währungsformat
        JFormattedTextField tfBetrag = 
            new JFormattedTextField(NumberFormat.getCurrencyInstance());

        // Wert für das Textfeld wird gesetzt
        tfBetrag.setValue(4.30);

        tfBetrag.setColumns(5);
 
        meinPanel.add(labelDatum);
        meinPanel.add(tfDatum);
        meinPanel.add(labelBetrag);
        meinPanel.add(tfBetrag);
 
        meinJFrame.add(meinPanel);
        meinJFrame.setVisible(true);
    }
}

Beispiel JFormattedTextField

Wir haben in unserem Beispiel zwei JFormattedTextFields erzeugt. Das erste dient zur Eingabe eines Datums. Dem Konstruktor wird als Wert ein Objekt der Klasse Date übergeben. Da keine anderen Werte vorgegeben wurden, wird das Date-Objekt mit dem aktuellen Datum initialisiert. Die zuständige DefaultFormatterFactory ermittelt anhand des Datentyps die passende Formatierungsklasse, in diesem Fall DateFormatter und setzt eine Instanz dieser Klasse als zuständigen Formatter für das Textfeld.

Das zweite Textfeld soll zur Eingabe eines Wertes im Währungsformat dienen. Dem Konstruktor wird eine Instanz der Formatklasse NumberFormat übergeben.

Um zu verstehen, wie die Formatter-Klassen die eingegebenen Zeichen parsen, spielen sie am besten ein wenig mit den Werten und wechseln dabei zwischen den Textfeldern hin und her. Sie werden dabei merken, dass die eingetragenen Zeichen dem jeweiligen Format entsprechen müssen, damit beim Wechseln des Fokus erhalten bleiben. Wenn Sie z. B. einen Wert in das erste Textfeld eintragen, welcher nicht dem Format entspricht, und wechseln dann in das andere Textfeld, wird das erste Textfeld auf den zuletzt gültigen Wert zurückgesetzt werden. Standardmäßig entspricht also das Verhalten bei Fokusverlust der Beschreibung der Konstante COMMIT_OR_REVERT.

In beiden Textfeldern werden, da nichts anderes vorgegeben ist, standardmäßig die lokalen Ländereinstellungen für die Formatierungen verwendet. Daher wird u.a. ein anderes Währungssymbol, wie etwa ein Dollarzeichen, vom Formatter beim Wechseln des Fokus bzw. Aufruf von commitEdit in ein Euro-Symbol umgewandelt.

Kleine Variationen in der Formatierung kann der Formatter oft trotzdem erfolgreich parsen und in das korrekte Format umwandeln. So "kennt" der Formatter beispielsweise auch Datumsangaben mit einstelligen Monatsangaben wie 2.2.2013. Auch kann der Währungsbetrag erfolgreich geparst werden, wenn Nachkommastellen weggelassen oder weitere hinzugefügt werden. Wichtig ist aber das Währungszeichen am Ende.


Unterthemen: