# JFormattedTextField und maximal 3 Stellen.



## Sym (10. Jan 2008)

Hallo,

ich möchte ein JFormattedTextField haben, welches einen int von max. 3 Stellen erwartet. Nur leider fehlt mir das richtige Pattern:


```
myField.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(new DecimalFormat("<PATTERN>"))));
```

So sieht mein Code bisher aus. Doch wie sieht <PATTERN> dann aus?

Gruß und Dank


----------



## Niki (10. Jan 2008)

Da ich lange mit Java 1.3 gearbeitet habe, habe ich die JFormattedTextFields nie gebraucht, das ganze würde auch so gehen:


```
JTextField tf = new JTextField();
	tf.setDocument(createNumericDocumentWithMaxLength(3));

private Document createNumericDocumentWithMaxLength(final int maxLength){
		
		Document doc = new PlainDocument(){
			@Override
			public void insertString(int offs, String str, AttributeSet a)
					throws BadLocationException {
				if(getLength() + str.length() > maxLength)
					return;
				if(!str.matches("^[\\d]*$"))
					return;
				
				
				super.insertString(offs, str, a);
			}
		};
		return doc;
		
	}
```


----------



## lhein (10. Jan 2008)

gehts noch komplizierter?


```
MaskFormatter formatter = new MaskFormatter("###");
JFormattedTextField myField = new JFormattedTextField(formatter);
```

das sollte genügen.

lr


----------



## Sym (10. Jan 2008)

@Niki: Das sieht nett aus, ist aber mMn viel zu oversized. Keep it simple. 

@LR: Damit erreichst Du aber auch, dass minimal 3 Stellen besetzt sein müssen.


----------



## lhein (10. Jan 2008)

Jo, das ist die Kehrseite der ....


----------



## Niki (10. Jan 2008)

Eben   
Deswegen meinen "komplizierten" Code verwenden, der macht was er soll.

Du kannst das ganze ja auch in ein abgeleitetes TextFeld packen, dann brauchst du immer nur sagen:

```
NumericTextField tf = new NumericTextField(3);
```


----------



## mimo (10. Jan 2008)

Versuch mal:


```
import java.awt.*;
import javax.swing.*;
import javax.swing.text.*;
import java.text.*;
import java.util.*;


/**
 * Formatiertes Textfeld für Eingaben von Integerwerte
 * gibt den Fokus nur weiter, wenn die aktuelle Eingabe
 * korrekt formatiert ist.
 */
   

public class JIntTextField 
extends JFormattedTextField
{
    
    //Variablen
    
    private InputVerifier inVeri = new JIntTextFieldVerifier();
    private MaskFormatter fm;
    private int alignment = JTextField.LEFT;
    private Font font = new Font("Arial", Font.PLAIN, 10);
    /*
     *Konstruktor IntTextFeld für 3 Ziffern
     */
    /** Creates a new instance of JMoneyTextField */
    public JIntTextField() {
        
        //Format für Textfeld erzeugen
        setHorizontalAlignment(alignment);
        setFont(font);
        //Formatierer-Factory für PlzMaske erzeugen und registrieren
        AbstractFormatterFactory ff = new DefaultFormatterFactory();
        setFormatterFactory(ff);
        //Falsche Eingabe
        setFocusLostBehavior(JFormattedTextField.COMMIT);
        //InputVerifier registrieren
        setInputVerifier(inVeri);
       
       
    }
    
    
     
}

class JIntTextFieldVerifier extends InputVerifier {
         
         public boolean verify(JComponent input) {
         boolean returnvalue = false;
         JFrame dialog = new JFrame("JIntTextField");  
         
             if (input instanceof JFormattedTextField) {
                 //InputVerifier wurde für JFormattedTextField registriert
                 // -> prüfe Eingabe mit Formatter des Textfelds
                 
                 JFormattedTextField ftf = (JFormattedTextField) input;
                 String vergleich = "";
                 String text = ftf.getText();
                 if (text.length()<1) {
                     returnvalue = true;
                 } else {
                     try {
                         Integer d = Integer.valueOf(text);
                         if(text.length()<=3){ returnvalue = true;} //überprüft die Anzahl der Stellen
                     } catch (NumberFormatException e) {
                         JOptionPane.showMessageDialog(dialog, "Bitte geben Sie max. drei Ziffern ein!");
                     }
                 }   
             }   
                     // -> Eingabe durchlassen
                     return returnvalue;
         }      
}
```


----------



## Sym (10. Jan 2008)

@LR: Das war aber nicht die Anforderung. 

@Niki: Ja, vielen Dank für Deinen Tipp. Aber der Formatter ist (wenn ich das richtig sehe) genau für solche Dinge vorgesehen. Und den würde ich gerne nutzen und verstehen.


----------



## Sym (10. Jan 2008)

@mimo: Auch Dir vielen Dank. Aber so möchte ich das nicht. 

@all: Ich weiß schon, wie ich das Problem lösen könnte. Ich möchte aber eine möglichst elegante Lösung. Und ich meine, der Formatter sollte sowas hergeben, oder nicht?


----------



## lhein (10. Jan 2008)

```
NumberFormatter nf = new NumberFormatter();
        nf.setAllowsInvalid(false);
        nf.setValueClass(Integer.class);
        nf.setMinimum(new Integer(0));
        nf.setMaximum(new Integer(999));
        JFormattedTextField myField = new JFormattedTextField(nf);
```

ist sicher nicht die beste Lösung, aber sollte gehen.

lr


----------



## *Hendrik (10. Jan 2008)

Ich würde bzw. verwende auch den "komplizierten" Code von Niki. Hier in den FAQs ist es noch mal beschrieben. Das JFormattedTextfield weist ein unschönes/anderes Verhalten als ein JTextfield auf, wenn man mit der Maus reinklickt (vielleicht auch beim reintaben), da das Feld automatisch mit Leerzeichen vorbelegt ist. D.h. wenn Du reinklickst landest Du u.U. irgendwo in der Mitte und nicht am Anfang. Im Grund musst Du also immer diese Leerzeichen überschreiben. (Soweit ich das noch in Erinnerung habe). Deswegen verwende ich lieber ein JTextField, erweitere ein PlainDocument und überschreibe dessen insertString() Methode. Dem erweiterten PlainDocument könntest Du zusätzlich Parameter übergeben, z.B. für die max. Anzahl der einzugebenen Zeichen oder/und ob es sich um ein alphanumerischen oder numerisches Feld handelt und entsprechend in insertString() behandeln. So kannst Du das Document noch für andere Textfelder verwenden.


----------



## lhein (11. Jan 2008)

```
NumberFormat nmf = new DecimalFormat("000");
        NumberFormatter nf = new NumberFormatter(nmf);
        nf.setAllowsInvalid(false);
        nf.setOverwriteMode(true);
        JFormattedTextField myField = new JFormattedTextField(nf);
```

Das ist fast noch einfacher 

lr


----------

