JTextField bzw JFormattedTextField

MScalli

Erfahrenes Mitglied
Hi Leutz.
Ich hab ein riesen Problem.

Es geht um die Prüfung eines JTextField bzw. JFormattedTextField.

folgendes Problem:
eine Zahl soll eingegeben werden.
länge, art der Zeichen(Integer, String usw.) soll vorgegeben sein und die nachkommastellen müssen fest sein(z.B. 4 nachkommastellen..bei eingabe von 1,2 soll es 1,2000 beim verlassen des Feldes werden und bei 1,23456 UNGERUNDET 1,2345.. also einfach der rest abgeschnitten werden.)

für die GESAMTLÄNGE der eingabe und die ART DER ZEICHEN habe ich eine Lösung..
aber ich glaub ich bin irgendwie auf ner falschen fährte.
Hier mal bisschen code von meinem ansatz.
Aber ich denke das wird so nicht ganz lösbar sein..

hier mal der das JFormattedTextField..
Code:
		tf_umrechnungsfaktor = new JFormattedTextField();
		tf_umrechnungsfaktor.setDocument(new DecimalDocument(10));
		tf_umrechnungsfaktor.setFont(MyParam.getTextFieldFont());
		tf_umrechnungsfaktor.setBounds(130, 110, 80, 25);
		tf_umrechnungsfaktor.setHorizontalAlignment(javax.swing.JTextField.RIGHT); 
		tf_umrechnungsfaktor.addFocusListener(new FocusListener(){

			public void focusGained(FocusEvent arg0) {
			}
			public void focusLost(FocusEvent arg0) {
				// Evtl beim verlasses die nachkommastellen abschneiden/0 anhängen
				System.out.println("Focus Verlassen!!");
			}
		});
	    pan_einkauf.add(tf_umrechnungsfaktor);

und hier die Klasse DecimalDocument..
Code:
import javax.swing.text.PlainDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.AttributeSet;

/**
 * Diese Klasse ist ein Dokument für Textfelder, welches...
 * 
 * 1. Eingabe auf x Zeichen begrenzt.
 * 2. Nur die Zeichen zulässt die in der Variable valid stehen
 *
 * Die Zuweisung geschieht über
 * JTextfield.setDocumenT(new Validation(int anzahl));
 */
public class DecimalDocument extends PlainDocument{

	private static final long serialVersionUID = 5032290234368360350L;
	
	private int limit;

    /**
     * Konstruktor für das Validationdokument
     * @param int limit: maximale Anzahl der einzugebenen Zeichen
     */
    public DecimalDocument(int newLimit){
        super();
        if (limit < 0){
            limit = 0;
        } else {
            limit = newLimit;
        }
    }

    /**
     * Funktion überschreibt die Methode insertString von PlaintDocument
     * @param int offset: Position
     * @param String str: der String
     * @param AttributeSet attr: Attributset
     */
    public void insertString (int offset, String str, AttributeSet attr) throws BadLocationException {
    	
        if (str == null) return;
       
        //Zeichenkette mit den gültigen Zeichen
        String valid = ".-,0123456789";
        
        for (int i=0; i<str.length();i++) {
        	System.out.println();
            if (valid.indexOf(str.charAt(i)) == -1) {
            	// wenn man hier rein kommt ist das eingegebene Zeichen ungültig!!
                return;
            }
            if ((getLength() + str.length()) > limit){
            	// wenn man hier rein kommt ist das übergebene limit erreicht
            	return;
            }
        //Wichtig Aufruf der übergeordneten Methode
        super.insertString(offset, str, attr);
    	}
    }
}

ist ein ziemlich komplexes problem...
ein kompletter neuanfang wär auch ok. auch ein normales JTextField nehmen wär ok.

plz help

gruss
MScalli
 
Hallo,

ich würde dafür einfach das java.text.DecimalFormat verwenden. In der Javadoc von der Klasse ist eine sehr gute Beschreibung mit Beispielen.

Grüße
Vincent
 
HILFEEEE

Habs jetzt einigfermassen hin gebracht.. leider gibts noch nen fehler.
kann sich das evtl. mal wer anschauen

probleme gibts nur bei der eingabe von 1 oder 2 stelligen zahlen..
z.B wenn ich 1 eingebe wird deas TextField mit 1,001,00 gefüllt
bei 22 wird es mit 22,0022,00 gefüllt..

ABER WIESO?

hier mal mein code.

der Aufruf
Code:
    pan_preise_bestaende.add(lbl);
		tf_standartpreis = new JFormattedTextField();
		tf_standartpreis.setDocument(new DecimalDocument(10));
		tf_standartpreis.setFont(MyParam.getTextFieldFont());
	    tf_standartpreis.setBounds(130, 10, 100, 25);
	    tf_standartpreis.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
		tf_standartpreis.addFocusListener(new FocusListener(){
			public void focusGained(FocusEvent arg0) {
				tf_standartpreis.setBackground(Color.YELLOW);
			}
			public void focusLost(FocusEvent arg0) {
				MyPrepareClass.prepareDecimal(tf_standartpreis, "######0.00", 10, 2);
				tf_standartpreis.setBackground(Color.WHITE);
			}
		});

die Klasse DecimalDocument

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

/**
 * Diese Klasse ist ein Dokument für Textfelder, welches...
 * 
 * 1. Eingabe auf x Zeichen begrenzt.
 * 2. Nur die Zeichen zulässt die in der Variable valid stehen
 *
 * Die Zuweisung geschieht über
 * JTextfield.setDocumenT(new Validation(int anzahl));
 */
public class DecimalDocument extends PlainDocument{

	private static final long serialVersionUID = 5032290234368360350L;
	
	private int limit;

    /**
     * Konstruktor für das Validationdokument
     * @param int limit: maximale Anzahl der einzugebenen Zeichen
     */
    public DecimalDocument(int newLimit){
        super();
        if (limit < 0){
            limit = 0;
        } else {
            limit = newLimit;
        }
    }

    /**
     * Funktion überschreibt die Methode insertString von PlaintDocument
     * @param int offset: Position
     * @param String str: der String
     * @param AttributeSet attr: Attributset
     */
    public void insertString (int offset, String str, AttributeSet attr) throws BadLocationException {
    	
        if (str == null) return;
       
        //Zeichenkette mit den gültigen Zeichen
        String valid = "-,0123456789";
        
        for (int i=0; i<str.length();i++) {
        	//System.out.println(str);
            if (valid.indexOf(str.charAt(i)) == -1) {
            	// wenn man hier rein kommt ist das eingegebene Zeichen ungültig!!
                return;
            }
            if ((getLength() + str.length()) > limit){
            	// wenn man hier rein kommt ist das übergebene limit erreicht
            	return;
            }
        //Wichtig Aufruf der übergeordneten Methode
        super.insertString(offset, str, attr);
    	}
    }
}
und noch MyPrepareClass mit der Methode
prepareDecimal
Code:
import java.text.DecimalFormat;

import javax.swing.JFormattedTextField;


public class MyPrepareClass {
	
	MyPrepareClass(){
		
	}
	
	public static String date_jjjjmmtt_To_ttmmjjjj(String _datum){
		
		String datum = _datum.substring(6) + "." + _datum.substring(4, 6) + "." + _datum.substring(0,4);
		return datum;
	}
	public static String getMaskFormatterString(int string_length) {
		String mask_format = "";
		for(int i = 0; i < string_length; i++){
			mask_format += "*";
		}
		return mask_format;
	}
	public static void prepareDecimal(JFormattedTextField ftf, String vorlage, int laenge, int nachkomma) {
		
		//System.out.println(ftf.getText().indexOf(","));
		
		if(ftf.getText().equals("")){
			return;
		}
		
		// String in ein char-Array packen und prüfen ob mehrere "," vorhanden sind
		char[] ch_hilf = new char[ftf.getText().length()];
		ch_hilf = ftf.getText().toCharArray();
		
		int komma_zaehl = 0;
		int minus_zaehl = 0;
		
		for(int i = 0; i < ch_hilf.length; i++){
			if(ch_hilf[i] == ','){
				komma_zaehl++;
			}
			if(ch_hilf[i] == '-'){
				minus_zaehl++;
			}
		}
		
		// Sind mehrere minus-Zeichen vorhanden, Textfeld löschen und Focus zurück setzten
		if(minus_zaehl > 1){
			MyError.setErrorText("M0100\nFehler: Mehrere Minuszeichen sind nicht zulässig");
			ftf.setText("");
			ftf.requestFocusInWindow();
			return;
		}
		
		// Sind mehrere kommas vorhanden, Textfeld löschen und Focus zurück setzten
		if(komma_zaehl > 1){
			MyError.setErrorText("M0100\nFehler: Mehrere Kommas sind nicht zulässig");
			ftf.setText("");
			ftf.requestFocusInWindow();
			return;
		}
		
		// passt die anzahl der vorkommastellen (wenn 1 komma vorhanden ist) 
		if(komma_zaehl == 1){
			String[] vor_nachkomma = ftf.getText().split(",");
			if(vor_nachkomma[0].length()> laenge - nachkomma - 1){
				MyError.setErrorText("M0100\nFehler: zuviele Vorkommastellen");
				ftf.setText("");
				ftf.requestFocusInWindow();
				return;
			}
		}
		
		// passt die anzahl der vorkommastellen (wenn kein komma vorhanden ist) 
		if(komma_zaehl == 0){
			if(ftf.getText().length()> laenge - nachkomma - 1){
				MyError.setErrorText("M0100\nFehler: zuviele Vorkommastellen");
				ftf.setText("");
				ftf.requestFocusInWindow();
				return;
			}
		}
		
		// erst "," durch "." ersetzten und Wert in einer Double Variablen merken
		double merk = Double.parseDouble( ftf.getText().replace(",", ".") );
		merk = merk + 0.00000001; // das wird hinzuaddiert da Java beim casten abrundet!
		
		// jetzt *10^nachkomma rechnen und nach Integer Casten(um nachkommastellen zu entfernen) 
		merk = merk * Math.pow(10,nachkomma);
		int merk_int = (int) merk;
		System.out.println("merk_int : " + merk_int);
		System.out.println("merk2 : " + merk);
		
		merk = (double) merk_int / Math.pow(10,nachkomma);
		System.out.println("merk3 : " + merk);
		
		// Format festlegen
		DecimalFormat df =   new DecimalFormat  ( vorlage );
		System.out.println("merk4 : " + df.format(merk));
		
		// formatiert zurück schreiben
		System.out.println("Hier stimmts noch :" + String.valueOf(df.format(merk)).replace(".", ","));
		ftf.setText(String.valueOf(df.format(merk)).replace(".", ","));
	}
}

ab ner 3stelligen zahl.. also z.B. 333 wird es einwandfrei angezeigt also 333,00
 
Zurück