Frage

Ich bin mit einem NumberFormatter und JFormattedTextField, aber die .getValue() kehrt nicht der gleiche Wert wie der Benutzer sieht.

ich denke, der Eingabe-Zeichenfolge analysiert wird unter Verwendung von Number analysieren-Methode, und ich erhalte die Number von NumberFormat.getNumberInstance(); mit dem aktuellen Locale. Also ich glaube nicht, dass ich es einfach meine eigene Parse-Methode erweitern und schreiben kann?

Im Beispiel , wenn der Benutzer 1234.487 die getValue() zurückkehren: 1234.487 aber der Benutzer wird 1,234.49

angezeigt

Ein weiteres Beispiel , mit NumberFormat.getCurrencyInstance();. Der Benutzer tippt 1234.487 und die getValue() kehrt 1234.487 aber der Benutzer wird $1,234.49 angezeigt

statt , ich mag ein ParseException erzeugt werden, wenn der Formatter nicht den Wert ohne Rundung formatiert. Das Gleiche gilt, wenn der Benutzer tippt 4.35b6, wird standardmäßig die Forma 4.35 angezeigt werden und der Wert wird 4.35, aber ich möchte ein ParseException, da der Benutzer in eine typisierte ungültig Wert.

Hier ist der Code, den ich versucht habe, mit:

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
final JFormattedTextField ftf = new JFormattedTextField(nf);
ftf.setValue(new BigDecimal("1234.50"));

// Print the value from ftf
final JTextField txt = new JTextField(12);
txt.addFocusListener(new FocusAdapter() {
    public void focusGained(FocusEvent e) {
        txt.setText(ftf.getValue().toString());
    }
});

Wie den gleichen Wert erhalten, wie der Benutzer zu sehen ist?

War es hilfreich?

Lösung

Sie sollten NumberFormatter erweitern, anstatt NumberFormat und außer Kraft setzen stringToValue, so dass es, dass überprüft, wenn die Zeichenfolge, die Sie den ursprünglichen Wert zurückbekommen werden analysiert:

class StrictNumberFormatter extends javax.swing.text.NumberFormatter {
    @Override
    public Object stringToValue(String text) throws ParseException {
        Object parsedValue = super.stringToValue(text);
        String expectedText = super.valueToString(parsedValue);
        if (! super.stringToValue(expectedText).equals(parsedValue)) {
            throw new ParseException("Rounding occurred", 0);
        }
        return parsedValue;
    }

    public StrictNumberFormatter(NumberFormat nf) {
        super(nf);
    }
}

NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
JFormattedTextField.AbstractFormatter formatter = new StrictNumberFormatter(nf);
final JFormattedTextField ftf = new JFormattedTextField(formatter);
ftf.setValue(new BigDecimal("1234.50"));

Dieser Formatierer wird den neuen Text ablehnen, wenn die Werte vor und nach der Rundung nicht übereinstimmen.

Hinweis: Dies vergleicht die Werte , nicht die Saiten. Es wird tolerieren Veränderungen wie Gruppierungszeichen entfernen ("$1,000" => "$1000") und Nullen ("$1.20" => "$1.2"). Im Grunde genommen, wenn die NumberFormat den gleichen Wert zurückkehrt, dann ist es akzeptabel. Aber alle vom NumberFormat auferlegten Beschränkungen gelten weiterhin, z.B. Sie müssen nicht das Währungssymbol entfernen oder führende Leerzeichen usw. eingefügt werden.

Andere Tipps

Versuchen Sie folgendes:

txt.setText(ftf.getFormatter().valueToString(ftf.getValue()));

Sie werden auch die java.text.ParseException handhaben müssen, dass die valueToString Methode löst.

Edit: Der Formatierer kann so eingestellt werden insgesamt ungültige Einträge zu verbieten, die helfen könnten:

    ((DefaultFormatter)ftf.getFormatter()).setAllowsInvalid( false );
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top