# Datumseingabe mit JFormattedTextField



## Guest (9. Jun 2005)

Hallo!

Ich möchte ein JFormattedTextField zur Datumseingabe benutzen. Das Datum soll in der Form dd.mm.yyyy eingegeben werden. Ich möchte allerdings, dass der Benutzer nur die Zahlen, nicht aber die Punkte zwischen den Datumsangaben eingeben muss. Mit

```
DateFormatter df = new DateFormatter(new SimpleDateFormat("dd.mm.yyyy"));
JFormattedTextField tfDate = new JFormattedTextField(df);
```
erreiche ich, dass nur gültige Daten eingegeben werden können, der User muss aber die Punkte zwischen den Datumseingaben explizit eintippen. Wenn ich nun

```
MaskFormatter mf = new MaskFormatter("##.##.####");
JFormattedTextField tfDate = new JFormattedTextField(mf);
```
verwende, dann sind müssen die Punkte zwischen den Datumsangaben nicht mehr eingegeben werden, aber es wird nicht überprüft, ob es sich bei der Eingabe um ein gültiges Datum handelt. 

Kann man die beiden irgendwie kombinieren, oder gibt es eine andere Möglichkeit?


----------



## Karl (10. Jun 2005)

Hallo,

grundsätzlich kann man solche Datumsfelder beliebig ausbauen (z.B. Assistenzfunktion für Punkte, etc), nur
eben nicht so einfach.

Falls Dir eine abschließende Prüfung reicht, hier ein Beispiel:


```
MaskFormatter mf = new MaskFormatter("##.##.####"); 
        JFormattedTextField tf = new JFormattedTextField(mf);
        tf.setInputVerifier(new InputVerifier() {
            private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
            public boolean verify(JComponent input) {
                boolean res = true;
                JTextComponent tc = (JTextComponent)input;
                String newContent = tc.getText();
                if (newContent.length() > 0) {
                    try {
                        Date d = sdf.parse(newContent);
                        
                        if (!sdf.format(d).equals(newContent)) {
                            tc.selectAll();
                            res = false;
                        }
                    }
                    catch (ParseException ex) {
                        tc.selectAll();
                        res = false;
                    }            
                }
                return res;
            }
        });
```

Für die meisten Anwendungen sollte das reichen. Du kannst natürlich auch einfach den Text leer setzen
und das Verlassen des Feldes erlauben, falls Du den Benutzer grundsätzlich nicht einsperren willst.

Ich bin mal gespannt, ob jetzt erboste Kommentare kommen, wie man alles Datumsfelder besser
gestalten kann    .

Gruß,
Karl


----------



## Guest (13. Jun 2005)

Vielen Dank für Deine Antwort. Das hat mir schon mal sehr geholfen! :toll: 

Eine Frage hab ich noch:
Ich habe eine eigene Klasse "DateInputField" erstellt, die von JFormattedTextField erbt. Den MaskFormatter habe ich dann im Konstruktor der Klasse erzeugt und mit setFormatter() gesetzt. Wenn ich das so mache scheint es aber nicht zu funktionieren. Die Punkte sind zwar da, man kann aber beliebig viele Zahlen und auch Buchstaben eingeben. Wenn ich allerdings den MaskFormatter dem Konstruktor mitgebe und im Konstruktor dann super(formatter); aufrufe, dann funktioniert es wie erwartet.

Weiß jemand warum das so ist?


----------



## Karl (13. Jun 2005)

Hallo,

Die API sagt zu setFormatter (übrigens protected)


> You should not normally invoke this, ...



Man soll stattdessen die Factory setzen. Dass Du so eine "halbe Funktion" beobachtest,
liegt wohl daran, dass innerhalb von JFormatted-Textfield nicht überall immer wieder
die Factory verwendet wird, an manchen Stellen aber schon.

Du musst übrigens keine Factory schreiben, es sollte reichen im Konstruktor von DateInputField zu schreiben:

```
this.setFormatterFactory(new DefaultFormatterFactory(meinNeuerGanzBesondererFormatter));
```

Was anderes macht der Konstruktor nämlich auch nicht.

Gruß,
Karl


----------



## Guest (13. Jun 2005)

Danke!


----------

