Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


8.6.14

JFormattedTextField



Abbildung 8.47: JFormattedTextField
Abbildung 8.47

Neu in Version [1.4]1.4 ist diese Erweiterung des JTextField, die eine Validierung der Eingabe ermöglicht. Dies geschieht über ein Exemplar der Klasse JFormattedTextField.AbstractFormatter. Typischerweise benutzt man hier die zwei Standard-Implementierungen DateFormatter (für Datumseingaben), NumberFormatter (für Zahlenwerte) und MaskFormatter (bei dem man Texteingaben nur nach einem bestimmbaren Muster eingeben kann). Alle drei Klassen sind im Paket javax.swing.text definiert. Neben der Möglichkeit, den Formatter direkt anzugeben, kann man auch eine JFormattedTextField.AbstractFormatterFactory angeben. Der Vorteil davon (wie bei allen Factories) ist, dass die Anzahl der Formatter-Exemplare von der Factory überwacht werden kann. Typischerweise hat die Factory nur ein Exemplar, welches von verschiedenen JFormattedTextFields gleichzeitig verwendet werden kann. Zu diesem Zweck wird beim Hin- und Herwechseln zwischen den Textfeldern die Methode install(JFormattedTextField field) bzw. uninstall() aufgerufen.

Die Überprüfung der Eingabe geschieht auf zwei Ebenen. Zum einen während der Eingabe der Zeichen (siehe JFormattedTextField.AbstractFormatter), wie auch bei dem Versuch, das Textfeld zu verlassen. In diesem Fall wird das schon bei Java 1.3 eingerführte Konzept des InputVerifier verwendet.

Ein InputVerifier verhindert das Versetzen des Fokus weg von einer Komponente, wenn diese falsche Eingaben hat. Zu diesem Zweck kann bei jeder Swing-Komponente die Methode setInputVerifier(InputVerifier verifier) aufgerufen werden. Über die Methode setVerifyInputWhenFocusTarget(boolean state) kann man bei einer Komponente verhindern, dass der InputVerifier aufgerufen wird - sinnvoll beispielsweise beim Abbrechen-Button.

  // Überprüft, ob "pass" eingegeben wurde
  class PassVerifier extends InputVerifier {
    public boolean verify(JComponent input) {
      JTextField tf = (JTextField) input;
      return "pass".equals(tf.getText());
   }
  }
  JTextField f = new JTextField();
  f.setInputVerifier(new PassVerifier());

Man kann dabei über die Methode setFocusLostBehavior(int behavior) zwischen vier Möglichkeiten wählen, was passieren soll, wenn versucht wird, das Textfeld zu verlassen:

All diesen Varianten ist gemeinsam, dass die Komponente verlassen wird. Wenn gewünscht wird, dass der Fokus erst die Komponente verlassen kann, wenn die Eingabe korrekt ist, kann man folgenden InputVerifier dafür benutzen:

  public class FormattedTextFieldVerifier extends 
                                        InputVerifier {
    public boolean verify(JComponent input) {
      JFormattedTextField ftf = (JFormattedTextField)input;
      JFormattedTextField.AbstractFormatter formatter = 
         ftf.getFormatter();
      if (formatter != null) {
        String text = ftf.getText();
        try {
          // Wenn die Konvertierung
          // des Textes zum gewünschten
          // Datum geht, liefert die Methode
          // ein positives Ergebnis
          formatter.stringToValue(text);
          return true;
        } catch (ParseException pe) {
            return false;
        }
      }
      return true;
    }
  }

JFormattedTextField.AbstractFormatter

Um eine implementierende Klasse dieser abstrakten Klasse zu bilden, müssen die Methode valueToString(Object obj) und stringToValue(String str) implementiert werden.

Dies wird nötig, da das Textfeld intern mit Strings arbeitet, die Daten aber beliebig sein können. Daher wird zu Beginn das Objekt in eine String-Repräsentation umgewandelt und nach dem Editiervorgang der neue String in das entsprechende, beliebige Daten-Objekt umgewandelt.

Zusätzlich kann der Programmierer ein Exemplar der Klasse javax.swing.text.DocumentFilter angeben, mit dem die Eingabe von bestimmten Zeichen validiert werden kann (s. Ausführungen zu JTextField).

Ein javax.swing.text.NavigationFilter hingegen bietet die Möglichkeit, die zulässigen Positionen für den Cursor innerhalb des Textfeldes zu definieren.

javax.swing.text.DateFormatter

Der DateFormatter bietet die Möglichkeit, Datumseingaben vorzunehmen. Zu diesem Zweck kann der Programmierer das Datumsformat im Konstruktor angeben. Das Format liefert dabei ein Exemplar der Klasse java.text.DateFormat. Um bspw. ein Datum der deutschen Form TT.MM.JJ editieren zu können, reicht folgender Code:

  JFormattedTextField tf = new JFormattedTextField(
       new DateFormatter(
         DateFormat.getDateInstance (DateFormat.SHORT, 
                                     Locale.GERMAN)));

Im Gegensatz zu dem MaskFormatter wird die Eingabe erst überprüft, wenn versucht wird, das Textfeld zu verlassen. Es ist also im obigen Beispiel möglich, zunächst Buchstaben statt Zahlen einzugeben.

javax.swing.text.NumberFormatter

Ähnlich wie beim DateFormatter wird die Eingabe erst beim bevorstehenden Verlust des Fokus überprüft. Mit Hilfe des Formates, das die Klasse java.text.NumberFormat vorgibt, können Zahlen nach einem bestimmten Schema editiert werden.

javax.swing.text.MaskFormatter

Im Gegensatz zu den vorher genannten Formatierern, werden hier die Tastatureingaben direkt überprüft. Dazu bildet man die passenden Muster anhand der in Tabelle 8.2 angegebenen Platzhalter.

Tabelle 8.2: Die Pattern des MaskFormatters
PlatzhalterBedeutung
#Eine gültige Zahl
'Escape-Zeichen, so dass eingeschlossener Text nicht als Platzhalter angesehen werden
UEin großgeschriebener Buchstabe. Bei der Eingabe eines kleinen Buchstaben wird dieser in einen großen umgewandelt.
LEin kleingeschriebener Buchstabe. Bei der Eingabe eines großen Buchstaben wird dieser in einen kleinen umgewandelt.
AEin Buchstabe oder eine Zahl
?Ein beliebiger Buchstabe
*Alles
HEin hexadezimales Zeichen (0-9, A-F bzw. a-f)

Um die Eingabe noch weiter einzugrenzen, können die gültigen Zeichen mit Hilfe der Methode setValidCharacters(String chars) als String-Aufzählung angegeben werden:

  // Nur hexadezimale Zahlen zulassen
  formatter.setValidCharacters("0123456789abcdefABCDEF");

Beispiel

  JFormattedTextField dateField = new JFormattedTextField(
        new MaskFormatter("##.##.####"));


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.