3

I want to remap the decimal comma (German keyboard) to a point for certain JTextFields. I have experimented with getInputMap() and getActionMap, but so far nothing worked. Best result I got so far was that the comma didn't work at all.

I think there should be some way using the input map, but how?

Below is a small example program, could someone give me a hint as to what to fill in at the location of the comment? Or is this completely wrong anyway?

import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

public class KeyTest extends JFrame {

    private JTextField textField;

    public KeyTest() {
        textField = new JTextField();
        add(textField);

        InputMap map = textField.getInputMap();
        map.put(KeyStroke.getKeyStroke(','), /* what to do here? */);
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                KeyTest test = new KeyTest();
                test.pack();
                test.setVisible(true);
            }
        });
    }
}

EDIT: Perhaps I was not clear enough with my question. There is no problem with normal numbers. I'm just looking to make user input more convenient when entering dates. these are in the format "DD.MM.YYYY" in Germany. That means, you cannot enter dates using just the numeric keypad because we do not have a decimal point, but a comma. That's why I want to replace comma with point in the textfields used for entering dates.

All the input fields for plain text and numbers already work fine, and even the date inputs work. I just want to make typing easier. Just yesterday I noticed a similar functionality in Libreoffice, where the comma on the numeric keypad (I have a German keyboard) gets replaced automatically in numerical cells (My locale is set to English), but only in cells containing numerical values. This also happens as you type.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Axel
  • 13,939
  • 5
  • 50
  • 79
  • why? If for formatting/parsing reasons, the answer below is correct, for others might be different (though I can't think of others right now :-) – kleopatra Aug 10 '12 at 12:29
  • I don't get it. I do live in Germany and I'm a German, too. But I never tried entering a date like 01,01,2012. But as I posted already the answer is still NumberFormat. If you cannot parse the number from one format (e.g. the default locale, lets say de), try parsing from en. But you have to make a decision if you want to show always "." as comma to the user or the locale representation of the comma(e.g. "," in Germany). – zip Aug 11 '12 at 11:32
  • This is not about parsing, but about remapping the comma on the numeric keypad to point. Perhaps you never had the need to quickly fill out a form with a lot of numeric and date fields. This is faster if you can enter all values just using the numeric keypad. – Axel Aug 13 '12 at 06:19

5 Answers5

3

As @MKorbel suggests, you might be able to use JFormattedTextField and supply a suitable Locale.

JFormattedTextField field = new JFormattedTextField(
    new NumberFormatter(NumberFormat.getNumberInstance(Locale.UK)));
field.setValue(new Double(123.45));
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
3
  • have to use JFormattedTextField or JSpinner with Number Formatter, rather plain JTextField, I haven't issue with decimal separator without setting for Locale

  • there is second way to use DocumentFilter rather than InputMask, for filtering un_wanted whitespace and non_numeric chars, and with to change dot to the desired decimal separator

  • notice by using DocumentFilter, output from JFormattedTextField or JSpinner Java internally to hold dot as ASCII decimal separator, there is only difference betweens view and model (Swing Document) in compare with DocumentFilter, there is returned changed grouping (space) and separator too

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Sorry, my question wasn't clear. It's not about formatting and parsing input, but about remapping the decimal comma to point as the user types. – Axel Aug 11 '12 at 10:05
2

What you are looking for is "NumberFormat" (http://docs.oracle.com/javase/6/docs/api/java/text/NumberFormat.html)

Example:

NumberFormat english = NumberFormat.getInstance(Locale.ENGLISH); 
Number n = english.parse("0.123");   //english notation
NumberFormat german = NumberFormat.getInstance(Locale.GERMAN);
System.out.println(german.format(n.floatValue())); //output 0,123 (german notation)
zip
  • 579
  • 1
  • 3
  • 16
  • No, definitely not. I know about that, but I want the comma to be replaced as the user types. – Axel Aug 11 '12 at 09:51
  • The answer is still NumberFormat. Add a textChangeListener to the JTextField and parse the input value with `NumberFormat.getInstance(...).parse(/*data from event here*/`. On error you got the wrong Locale, try again with default. Set the value to the textField and you are done – zip Aug 11 '12 at 11:35
1

Use the following

textField.addKeyListener(new KeyListener(){

  public void keyTyped(KeyEvent e) {
    char c = e.getKeyChar();
     if (c== ',')
       e.setKeyChar('.');
  }
});
Roman C
  • 49,761
  • 33
  • 66
  • 176
0

I found another way to manage the comma/dot problem which is easy and short. This solution should work all over the world and is not depending on the kind of your keyboard and or your LOCALE settings.

I'm using the JFormattedTextField for to get the right Localized output and add ".replace(',', '.')" to the parseDouble() function as show in the example bellow.

private void ConvertMilesToKilometers() {

 Double inputNumber = 0.0;

 // to format the output string
 DecimalFormat df = new DecimalFormat("#,###.##");

 // another way will be to use LOCALE 
 // DecimalFormat df = (DecimalFormat)NumberFormat.getNumberInstance(Locale.GERMANY);

 // get user input
 try {
     inputNumber = Double.parseDouble(milesTextField.getText().replace(',', '.'));
 } catch (Exception e) {
     JOptionPane.showMessageDialog(this, "please enter a valid number!", null, JOptionPane.ERROR_MESSAGE);
 }

    // calculate and give the answer 
    String answer = df.format(inputNumber * 1.609344f);
    this.KilometersLabel.setText(answer + " Kilometers."); 

    // clear the input field 
    this.milesTextField.setText("");
}

I hope this will help. Regards from Germany.

Rene Salu
  • 1
  • 1