0

I have create a custom JTextFields that can accept only number values.

So I have this:

package com.mcsolution.common.Componenti_Swing;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import com.mcsolution.common.supporto.VisualMessage;


public class DoubleTextFieldFormat extends TextFieldFormat{

    /**
     * 
     */
    private static final long serialVersionUID = 8856130645860365803L;
    public DoubleTextFieldFormat(){
        addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char ch = e.getKeyChar();

                if (!isNumber(ch) && !isValidSignal(ch) && !validatePoint(ch)  && ch != '\b') {
                    e.consume();
                }
            }
        });

    }

    public DoubleTextFieldFormat(Font font,Boolean isSelectedAll,Integer horizzontalAlignment,
            Integer numberCharacter,String text,Dimension preferredSize,
            Boolean isEditable){

        if(font!=null)
            this.setFont(font);

        if(isSelectedAll){
            this.addFocusListener(new FocusListener() {
                public void focusGained(FocusEvent e){
                    selectAll();
                }
                public void focusLost(FocusEvent e){
                }
            });
        }
        if(horizzontalAlignment!=null)
            this.setHorizontalAlignment(horizzontalAlignment);

        if(numberCharacter!=null)
            this.setDocument(new PersonalizzaJtextField(numberCharacter));

        if(text!=null)
            this.setText(text);
        if(preferredSize!=null)
            this.setPreferredSize(preferredSize);

        if(isEditable!=null)
            this.setEditable(isEditable);

        addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char ch = e.getKeyChar();

                if (!isNumber(ch) && !isValidSignal(ch) && !validatePoint(ch)  && ch != '\b') {
                    e.consume();
                }
            }
        });
    }

    private boolean isNumber(char ch){
        return ch >= '0' && ch <= '9';
    }

    private boolean isValidSignal(char ch){
        if( (getText() == null || "".equals(getText().trim()) ) && ch == '-'){
            return true;
        }

        return false;
    }

    private boolean validatePoint(char ch){
        if(ch != '.'){
            return false;
        }

        if(getText() == null || "".equals(getText().trim())){
            setText("0.");
            return false;
        }else if("-".equals(getText())){
            setText("-0.");
        }

        return true;
    }

    public Double getValue(){
        try{
            String valore = this.getText();
            valore= valore.replaceAll(",", ".");
            return Double.parseDouble(valore);
        }catch(Exception e){
            VisualMessage.getErrore();
            return null;
        }
    }
}

Now if I want retrieve the value I use this code:

Double val = myTextField.getValue();

This method works not every times.

For example if I have this value into TextField 1.900,50 if have an errore.

How can I convert the value in this format x.xxx,xx?

bircastri
  • 2,169
  • 13
  • 50
  • 119
  • 1
    Don't use a `KeyListener` to filter a text component, use a a `DocumentFilter` instead. See [Implementing a Document Filter](http://docs.oracle.com/javase/tutorial/uiswing/components/generaltext.html#filter) and [DocumentFilter Examples](http://www.jroller.com/dpmihai/entry/documentfilter) for more details. – MadProgrammer Oct 28 '15 at 10:47
  • 1
    You should use either a `JSpinner` or `JFormattedTextField` as they already provide this functionality. See [How to Use Spinners](http://docs.oracle.com/javase/tutorial/uiswing/components/spinner.html) and [How to Use Formatted Text Fields](http://docs.oracle.com/javase/tutorial/uiswing/components/formattedtextfield.html) for more details – MadProgrammer Oct 28 '15 at 10:47
  • Personally, I'd remove the formatting (`,`) and then rely on `Double.parseDouble` – MadProgrammer Oct 28 '15 at 10:48
  • is 1.900,50 a valid number format? Number separator after the decimal point? – Bon Oct 28 '15 at 10:50
  • yes, and @MadProgrammer I can't remove (,) because this character is decimal separator – bircastri Oct 28 '15 at 11:07
  • @bircastri Not to a `double` it isn't. You're confusing the "format" with the "value" – MadProgrammer Oct 28 '15 at 11:11
  • how can I fix this problem? – bircastri Oct 28 '15 at 11:19
  • 1
    Possible duplicate of [Java big decimal number format exception](http://stackoverflow.com/questions/22454133/java-big-decimal-number-format-exception) – Erwin Bolwidt Oct 28 '15 at 12:11
  • You are using a number in a European (probably Italian, considering your profile) locale. Don't use `Double.parseDouble` because it expects something very close to the US locale. See the answer I voted as a duplicate of this question. Instead of Locale.GERMAN, use Locale.ITALIAN (although the German Locale can also parse numbers in your format). And in that case, don't replace the comma with a dot. – Erwin Bolwidt Oct 28 '15 at 12:14

1 Answers1

0

I have fixed my error, I have change my getValue() method with this:

public Double getValue(){
    try{
        NumberFormat nf = NumberFormat.getInstance(Locale.getDefault());
        //String valore = ;
        return nf.parse(this.getText()).doubleValue();

    }catch(Exception e){
        VisualMessage.getErrore();
        return null;
    }
}
bircastri
  • 2,169
  • 13
  • 50
  • 119
  • So now your code only works for ITALIAN locale (and similar). What about using Locale.default to support the users setting. Haven't looked into your code to see if this is the only thing needed to support all locales. – mattiash Oct 29 '15 at 07:46