# Eingabe auf Zahlen beschränken



## DasBiest (11. Nov 2003)

Ich weiß, dass ein ähnliches Thema hier schon mal behandelt wurde, aber leider hat mir das nicht weiter geholfen.
Ich habe ein Textfeld in das nur Zahlen eingegeben werden sollen und ansonsten soll eine Fehlermeldung erscheinen. Mein Problem liegt jetzt darin, wie ich das vernünftig abfrage.
Mein erster Versuch:

```
void jTextField1_keyPressed(KeyEvent e)
  {
    int i;
      try
      {
       //Das ist Mist!!!!!
        i = Integer.valueOf(jTextField1.getText()).intValue();
      }
    catch (NumberFormatException ex)
    {
      JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben");

    }
```
Aber das ist doch sehr unglücklich 

Wie überprüfe ich vernünftig, ob ich eine Zahl oder einen Buchstaben eingebe??


----------



## Stefan1200 (11. Nov 2003)

Sorry, habe nicht gesehen, das du diese Variante schon kennst.
Ich lasse es trotzdem nochmal stehen für spätere Besucher mit ähnlichen Problemen.

Hmm, eine Möglichkeit wäre so:


```
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int eingabe = 0;

while (true)
{
    System.out.println("Bitte geben Sie eine Zahl ein:");
    try
    {
        eingabe = Integer.parseInt(br.readLine());
    }
    catch (NumberFormatException e)
    {
        System.out.println("Nur Zahlen eingeben!");
        continue;
    }
}

System.out.println("Juhu, Sie haben eine Zahl eingegeben!");
```

Vielleicht hilft dir das weiter.


----------



## DasBiest (11. Nov 2003)

Hm, das hilft mir jetzt ja auch nicht weiter.
Das Problem ist, das jetzt egal was ich eingebe, er grundsätzlich alles anmeckert, sprich bei jeder Eingabe das Infofenster aufpoppt. Und das soll er ja nur bei Buchstaben machen.
Wie müsste das aussehen???
Variable deklarieren, gucken ob Zahl oder Buchstabe, dafür jeweils true oder false setzen und davon abhängig die Try, catch Klausel steuern???
Wie mach ich das in Code??????


----------



## jptc.org (11. Nov 2003)

ist zwingend erforderlich die Eingabe ständig zu prüfen? Würde es nicht reichen bei der Bestättigung eines OK-buttons oder ähnlichen eine Prüfung aller eingebener Werte vorzunehmen? Prinzipiell sollte es mit Integer.parseInt() gehen, die Methode liefert auch gleich ein int zurück. Am besten ist Du trimst auch noch die Eingabe, denn Leerzeichen am Ende oder Anfang interessieren meist nicht wirklich. Bei der ständigen Überprüfung auf das KeyPressed-Event kommt es schnell zu einem flackerntem Eingabefeld.

Ich hoffe das konnte helfen.

Karsten Voigt
http://www.java-performance-portal.org


----------



## Mick (11. Nov 2003)

```
void jTextField1_keyPressed(KeyEvent e)
  {
    int i;
      try
      {
        i = Integer.parseInt(jTextField1.getText().trim());
      }
    catch (NumberFormatException ex)
    {
      JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben");

    }
```


So macht man das normalerweise.

Grüße,
Mick

[edit]da war einer schneller [/edit]


----------



## gustav (11. Nov 2003)

Ich nehme mal an, das Du was grafisches hast. Dann lässt Du dich bestimmt nach jedem Tastendruck oder zumindest nach dem Bestätigen informieren.
Entweder Du checkst jetzt nach jedem Tastendruck ob das letzte Zeichen in Deiner Eingabe noch stimmt (if (eingabe.charAt( ende) >='0') && ( ...<='9')) )  ODER Du gehst Deine gesamte Eingabe mit einer Schleife durch und prüfst dann.


```
void jTextField1_keyPressed(KeyEvent e)
  {
    String tex = jTextField1.getText() ;
    int len = tex.length() ;
     
    if (len > 0)  // falls die Eingabe leer ist
      if  ( ! ( (tex.charAt(len-1)>='0') && (tex.charAt(len-1)<='9')) ) 
      {
        JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben");
      }
  }
```

Hab ich jetzt nicht ausprobiert aber die Richtung sollte in etwa stimmen.....


----------



## DasBiest (12. Nov 2003)

Also optimal wäre, wenn eine Eingabe von Zahlen gar nicht möglich wäre, aber das ist wohl noch etwas zu hoch für mich 

Zu euren Vorschlägen:
Ich habe das mit 

```
try
      {
        i = Integer.parseInt(jTextField1.getText().trim());
      }
    catch (NumberFormatException ex)
    {
      JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben");
      jTextField1.setText("");
    }
```

ausprobiert, aber da erscheint bei jeder Eingabe egal ob Zahl oder Buchstabe das Info-Fenster?!?!?

Und bei :

```
String tex = jTextField1.getText() ;
    int len = tex.length() ;

    if (len > 0)  // falls die Eingabe leer ist
      if  ( ! ( (tex.charAt(len-1)>='0') && (tex.charAt(len-1)<='9')) )
      {
        JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben");
      }
```

Ist das Problem, dass er nach der Eingabe des 2ten Buchstaben oder der Zahl nicht prüft, d.h. ich kann z.B. 9p in das Textfeld eingeben, ohne das er es anmeckert 
Ich verzweifel hier noch *schluchz*
In C war das alles viel einfacher!!!!!


----------



## gustav (12. Nov 2003)

Sorry hab einige Feinheiten nicht beachtet !

Also, die keypressed Message ist nur bedingt für Dein Problem geeignet (zumindest mit meiner Lsg), da erst der Tastendruck bearbeitet wird und dann erst der String in jTextField1 angepasst wird. Kurz gesagt, die Methode hinkt immer einen Eingabeschritt hinterher. Eine Lösung wäre nun einfach die Taste die gedrückt wurde abzufragen - dafür gibts ja http://java.sun.com/j2se/1.4.2/docs/api/ unter KeyEvent !!!

```
void jTextField1_keyPressed(KeyEvent e)
  {
    char zeichen = e.getKeyChar() ;
    if (! ( (zeichen >= '0') && (zeichen <= '9')))
    {
      JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben") ;
    }
  }
```
Nachteil ist allerdings, das hier jetzt nur wirkliche Zahlen durchgelassen werden und z.B. Sondertasten wie Backspace ebenfalls Fehlermeldungen provozieren. Natürlich kannst Du diese Taste noch extra in Deinen Code unterbringen.

Mein 2. Vorschlag lehnt sich an den gestrigen an, benutzt aber die  keyReleased Message. Hierbei sollte die Methode erst aufgerufen werden, wenn der String bereits in jTextField1 angepasst wurde. Allerdings mußt Du hier den String dann von Hand wieder einkürzen. Eventuell ruft Java dann auch die Methode mehrmals hintereinander auf (es wird ein setText() gemacht) Das kannst Du dann aber extra herausfinden und ist eventuell nur für das PerformanceTuning wichtig....


```
void jTextField1_keyReleased(KeyEvent e)
  {
    String tex = jTextField1.getText() ;
     int len = tex.length() ;

     if (len > 0)  // falls die Eingabe leer ist
     {
       char zeichen = tex.charAt(len -1) ;
       if (! ( (zeichen >= '0') && (zeichen <= '9')))
       {
         JOptionPane.showMessageDialog(this, "Bitte nur Zahlen eingeben") ;
         
         // String berichtigen !!!!
         jTextField1.setText( tex.substring(0, len-1));
       }
     }
  }
```


----------



## DasBiest (13. Nov 2003)

@Gustav
Ich hab jetzt mal deinen 2ten Vorschlag übernommen und bis jetzt funzt das sehr gut.
Herzlichen Dank!!


----------



## DasBiest (14. Nov 2003)

Ich habe jetzt ein neues Prob wegen der Abfrage 
Und zwar möchte ich, dass wenn ich in dem Textfield "Enter" drücke, der Cursor ins nächste Fenster springt. An und für sich kein Prob, allerdings wenn ich das mit in die keyReleased-Methode einbaue, habe ich das Problem, wenn ich einen Buchstaben eingebe und das Infofenster hochpoppt und ich das dann mit "Enter" bestätige, der Cursor ins nächste Textfield springt. Habe dann versucht, das ganze mit Hilfe einer Variable zu umgehen, aber das funzt leider auch nicht 
Hat jemand vielleicht ne Idee wie ich das löse??

```
void jTextField1_keyReleased(KeyEvent e)
  {
    String tex = jTextField1.getText();
    int len = tex.length();
    boolean i = true;

    if (len > 0)  //falls die Eingabe leer ist
    {
      char zeichen = tex.charAt(len -1);
      if (!((zeichen >= '0') && (zeichen <= '9')))
      {
        JOptionPane.showMessageDialog(this, "Bitte nur ganze Zahlen eingeben!");
        i=false;
        //String berichtigen!!!
        jTextField1.setText(tex.substring(0, len-1));
      }
    }//If_Ende

   //Weiter mit Enter
    if ((e.getKeyCode()==KeyEvent.VK_ENTER ) && (i==true))
    {
      jTextField2.requestFocus();
    }//IF_Ende

  }
```


----------



## gustav (17. Nov 2003)

Deine Variable ist nur lokal für die Methode sichtbar. Eventuell wird durch das drücken der ENTER Taste ein neues Event für dich ausgelöst. Dieses durchläuft natürlich den gesamten Code (incl boolean i = true).
Versuch es mal mit eines globalen Variante. Allerdings würde ich sagen, das es dann Probleme mit der richtigen Unterscheidung zwischen den Enter's gibt.


----------



## Guest (17. Apr 2007)

Komt ein wenig spät, aber ... 

Eine weitere Möglichkeit wäre die Methode 
	
	
	
	





```
JTextField.getDocument().insertString(..)
```
 zu überschreiben.


```
public void insertString(int offset, String s, AttributeSet attributeSet) throws BadLocationException {
	try {
		Integer.parseInt(s);
	} catch (NumberFormatException e) {
		return;
	}

	super.insertString(offset, s, attributeSet);
}
```

Ich habe das nicht getestet aber so müsste es im Grunde genommen aussehen.


----------



## daily (2. Mai 2007)

Hab zu dem Thema hier noch eine andere Lösung. Und zwar als Document das man für das TextField verwenden kann. Schmankerl hierbei ist dass man noch einen Wert übergibt der die maximale Anzahl Zeichen für das Textfeld angibt.


```
import java.awt.Toolkit;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class StandardDocumentNumbers extends PlainDocument {

	private int maxLength_ = Integer.MAX_VALUE;

	public StandardDocumentNumbers(int maxLength) {
		this.maxLength_ = maxLength;
	}

	public void insertString(final int offset, final String toInsert,
			final AttributeSet notUsed) throws BadLocationException {
	
		if (toInsert == null) return;		
		
		int actualLength = this.getLength();
		boolean isInt = true;
		
		if (actualLength + toInsert.length() < this.maxLength_) {
			String [] splitted = toInsert.split("");
			
			for (int i = 1; i< splitted.length; i++){
				
				if (!(splitted[i].toString().equals("1") || splitted[i].toString().equals("2") || splitted[i].toString().equals("3") 
						|| splitted[i].toString().equals("4") || splitted[i].toString().equals("5") 
						|| splitted[i].toString().equals("6") || splitted[i].toString().equals("7") 
						|| splitted[i].toString().equals("8") || splitted[i].toString().equals("9") 
						|| splitted[i].toString().equals("0"))) isInt = false;
			}
			
			if (isInt) super.insertString(offset, toInsert, notUsed);
			
		} else {
			Toolkit.getDefaultToolkit().beep();
		}
	}

}
```


----------

