Java - JTextField + Document + Datumseingabe + Bitte helft mir =)

Sirial

Grünschnabel
Hallo,

ich bin Java Anfänger und schreibe gerade ein Programm in dem ich Textfelder benutze in dem ein Datum eingegeben wird um eine suche zu starten. Um die Datumseingaben festzulegen und zu begrenzen damit nicht irgendein Blödsinn eingegeben werden kann, benutze ich ein Document welches ich auf das Textfeld setzte. (verbessert mich gerne wenn ich da etwas falsch versteh ;)).
das Datum hat ein Format dd-mm-yyyy. Außerdem kann auch -1 (für gestern) und -2 (für vorgestern) eingegeben werden (berechnet wird dies in einer anderen Klasse um die geht es hier aber gerade nicht).

Mein Problem ist jetzt, das ich soweit meine eingabe ganz gut begrenzt habe. Jedoch wenn ein Datum eingegeben wurde und man sich evtl verschrieben hat (anstatt den 14-10 wollte man den 04-10 schreiben) und man mit dem Kürser zu dieser stelle geht um dies zu verbessern kann man die eingabe zwar löschen jedoch nix neues mehr eintragen. Das Datum muss erst komplett wieder gelöscht werden um eine neue Eingabe machen zu können. Mir ist klar das ich irgendwie die schleifen umbauen oder was einbauen muss aber ich probiere schon seit stunden daran und komm einfach an keine lösung =(

Da ich jedes mal wenn ich probleme habe hier im Forum gucke und mir bist jetzt immer wunderbest durh bestehnde beiträge geholfen wurde frage ich euch ob ihr mir evtl weiterhelfen könntet =)!! das wäre nett ;) bräuchte eine Löscung wenn möglich bis Freitag =)!!

Vielen Dank im Voraus

Mit freundlichen Grüßen

Sirial

hier mein Code:

Code:
	class DateDocument extends PlainDocument {

		  public void insertString(int offs, String str,
		                           AttributeSet a)
		                           throws BadLocationException {		  
		     // Überprüfen, ob nur Zahlen und Bindestriche eingegeben werden
		     for (int i = 0; i < str.length(); i++) {
		         char c = str.charAt(i);
		         if (c != '-' && (c < '0' || c > '9'))
		            return;
		     }  
		     
		     String text = getText(0, getLength())+str;		  
		     // genemigt das ein "-" am anfang eingegebn werden kann
		     if (text.length() == 1){
		    	 if (text.equals("-")){
		    	 super.insertString(offs, str, a);
		    	 return;
		    	 }		    	 
		     }
		     // genemigt dann auch die -1 oder -2
		     if (text.length() == 2){
		    	 if (text.equals("-1") || (text.equals("-2"))){
		    		 super.insertString(offs, str, a);
		    		 return;
		    	 }
		    	 
		    	 if (text.startsWith("-")){
		    		 return;
		    	 }
		     }
		     // fehler abfangen
		     if (text.length() >2){
		    	 if (text.startsWith("-1") || text.startsWith("-2")){
		    		 return;
		    	 }
		     }
		      // 1. Stelle Tag
		      if (text.length () > 0)
		         if (Integer.parseInt(text.substring(0, 1)) > 3)
		            return;
		     // Tag
		     if (text.length () >= 2 ) {
		    	 if (text.endsWith("-")){
		    		 return;
		    	 }
		    		 int date = Integer.parseInt(text.substring(0, 2));
		    		 if (date < 1 || date > 31)
		    			 return;
		     }
		     // Zweiter .
		     if (text.length() >= 3){
		        if (text.charAt(2) != '-')
		        	return;
		     }
		     // 1. Stelle Monat
		     if (text.length() >= 4)
		        if (text.charAt(3) != '0' &&
		           text.charAt(3) != '1')
		           return;
		     // Monat
		     if (text.length() >= 5) {
		        int month = Integer.parseInt(text.substring(3, 5));
		        if (month == 0 || month > 12)
		           return;
		        }
		    // Dritter .
		    if (text.length() >= 6){
		        if (text.charAt(5) != '-')
		           return;
		    }
		    
		    if (text.length() == 7){
		    	if (text.endsWith("-")){
		    		super.insertString(offs, str, a);
		    		return;
		    	}
		    }    
		    
		    // Maximale Länge
		    if (text.length() > 10)
		       return;
		    // Striche einbauen
		    if (text.length() == 2 || text.length() == 5)
		       str += "-";
		  
		    // Wenn die Eingabe korrekt ist,
		    // kann die super-Methode aufgerufen werden
		    super.insertString(offs, str, a);
		    }
		  }
 
Howdie.

Spontan kann ich zwar nicht alle deine Operationen nachvollziehen, aber prinzipiell könntest du das wesentlich einfacher haben. Ich hatte ein ähnliches Problem, da hab ich mir ein RegEx-Pattern erzeugt. Vielleicht willst du sowas mal in Erwägung ziehen. Ich hab jetzt mal auf die Schnelle einen regulären Ausdruck erzeugt, wie er ungefähr aussehen könnte:
Java:
	public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
		
		String pattern = "(-?)([0-9]{1,2})\\.([0-9]{1,2})\\.([0-9]{4})";

		if(Pattern.matches(pattern, str)){
			super.insertString(offset, str, attr);
		}
	}
Die runden Klammern sind nicht immer nötig, dienen aber der besser Übersicht. Das Pattern bedeutet soviel wie
  • Bindestrich - oder nicht
  • Ein oder zwei Zahlen von 0 - 9
  • Ein Punkt (Escaped, da ein RegEx-Zeichen)
  • Nochmal Schritt 2 - 3
  • Am Ende vier Ziffern von 0 - 9

Dann müssten deine Eingaben funkionieren, egal in welcher Reihenfolge sie eingetragen oder korrigiert werden, da immer der ganze String überprüft wird.

Gruß
miffi
 
Zuletzt bearbeitet:
Hi,

vielen Dank für die schnell Antwort =)!! Ich habs richtig verstanden das ich meinen krempel gegen deinen ersetzt habe? ich hab meins mal auskommentiert und deine Lösung eingebaut jedoch kann ich nun gar nichts mehr eingeben =(! Kenn mich leider nicht so gut mit regex aus und seh daher nicht genau wo denn nun mein fehler ist! oder obs überhaupt an dem regex liegt oder an was anderem.
Hast du den Codeschnipsel selber mal ausprobiert =)?

über weitere Antworten/Lösungsvorschläge würde ich mich freuen!

Vielen Dank!

MfG Sirial
 
Ja, du hast es richtig verstanden: Deinen "Krempel" ersetzen ;)

Wie gesagt, mein regulärer Ausdruck war nur auf die Schnelle zusammengeschustert und nicht getestet. Momentan fehlt mir leider die Zeit, das zu wirklich auszuprogrammieren. Falls ich heute im Laufe des Tages noch dazu komme, werde ich das noch tun.

Es sollte auch eher ein prinzipieller Anreiz sein, wie du vorgehen könntest und wie ich es getan habe. Wenn du Lust und Zeit hast, taste dich doch langsam mal ran und versuch erstmal nur Zahlen einzugeben usw.

Das Galileo-Tutorial hat mir persönlich gut geholfen:
http://openbook.galileocomputing.de...04_006.htm#mj602ac16531b46e2febaea06498cfffd2

Gruß
miffi
 
Danke danke soweit =)..
hab mich nun ein wenig mit regex auseinandergesetzt..
Nun stellt sich mir die Frage: Funktioniert das mit den Regulären Ausdrücken überhaupt innerhalb eines Documents welches auf das Textfeld gesetzt wird?
Ich habe so das gefühl das sobald ich die eingabe ein wenig einschrecke (nur zahlen geht ja noch aber sobald extra bedingungen dazukommen) das dann gar keine eingaben mehr akzeptiert werden auser wenn man ein Datum irgendwo vorschreibt und durch copy&paste in das Textfeld einfügt...
Ist Regex bei meinem Problem wirklich die bessere Lösung? kann man das Problem nicht einfacher Lösen? Oder wie setzte ich die Ausdrücke richtig um? Momentan bin ich ziemlich ratlos da meine Anfangslösung sobald man eine Veränderung an dem Datum nachträglich vornimmt immer zu Fehlern kommt ohne das ich einen Weg finde diese zu beheben =(...
Mit Regex komm ich da irgendwie auch nicht weiter..
Was mach ich falsch?

Ich Bitte um weitere Lösungsvorschläge oder Ansätze =)!!

Vielen Dank im Voraus


MfG Sirial
 
Mit JFormattedTextField habe ich angefangen bevor ich zu der Document Lösung kam.. Das hat irgendwie nicht so schön Funktioniert wie ich mir das erhofft hatte.. vllt hab ich da auch was falsch gemacht wer weiß..
So auf die schnell finde ich da mit dem Formattierten Textfeld und dem Regex leider keine Lösung =(..(bin auch bisschen unter zeitdruck da ich noch anderes nebenbei machen muss :/ ... wenn ich nicht bald eine Lösung dazu finde dann lass ich den User einfach alles eintippen was er will und erst bei dem Buttonklick also beim ausführen wird das Datum überprüft, das ist ja noch wesentlich einfacher und führt zu weniger Problemen/Bugs ;)).
Wie man evtl den Fehler umgehen könnte wäre, das wenn die Datumslänge größer als 6 entspricht (sprich: 14-02-) dann darf man nicht mehr löschen oder muss das ganze Datum löschen und erneut eingeben falls man sich verschrieben hat oder des ähnlichen..
Kann ich es irgendwie zulassen das wenn das Datum gelöscht werden soll zwangsweise alles gelöscht werden muss?
Ich denke das wäre eine angenehme Lösung..
Was meint ihr dazu =)?

Ich danke wieder im Voraus ;)!!

MfG Sirial
 
Howdie.

Ich hab jetzt auch mal ein bisschen mit dem JFormattedTextField rumgespielt. Es ist zwar praktisch für eine Maske, jedoch absolut unflexibel.

Wenn man z.B.
Java:
MaskFormatter formatter = null;
try{
	formatter = new MaskFormatter();
	formatter.setMask("##.##.####");
	formatter.setValidCharacters("0123456789");
	formatter.setPlaceholderCharacter('0');
} catch (ParseException pEx){
	pEx.printStackTrace();
}
JTextField textField = new JFormattedTextField(formatter);
benutzt, stimmt zwar die Anzahl der Ziffern und Punkte, jedoch kann man damit weder die eingebbaren Zahlen einschränken noch das Minus-Zeichen für deine Vorgestern- und Gestern-Methodik anwenden. Aber falls du das anders lösen kannst, wäre JFormattedTextField nicht blöd....

Die regulären Ausdrücke sind zwar möglich, aber wesentlich komplexer, als ich im ersten Moment angenommen habe... Ich hab anfangs gar nicht daran gedacht, dass die Eingabe ja Zeichen für Zeichen erfolgt. Das wird so ein riesen Ausdruck, dass du gerade deine eigene Verfikation weiter verwenden kannst.

Was du noch ausprobieren könntest, wäre eine Mischung aus RegEx und JFormattedTextField, wie sie z.B. hier zu sehen ist:
http://www.java2s.com/Tutorial/Java/0240__Swing/RegexFormatterwithaJFormattedTextField.htm

Ich hab nochmal nachgeschaut, wie ich das damals im Endeffekt gelöst hab mit dem Datum: Statt einer Verfikation der Eingabe hab ich einfach nen Kalender implementiert, mit dem das Datum ausgewählt werden kann ;)
Sorry, mehr fällt mir im Moment auch nicht ein...

Viel Erfolg noch + Gruß
miffi
 

Neue Beiträge

Zurück