2014-09-18 2 views
0

Я не нашел java вопрос, который помог мне решить мою проблему, поэтому здесь я прихожу.NumberFormatter не ведет себя так, как ожидалось

В настоящее время я пытаюсь использовать NumberFormatter с JFormattedTextField форматировать цену в GUI, как пользователь вводит его в.

Но я получаю странные результаты после ввода 2 цифры в текстовое поле.

Вот код, который я использовал для тестирования (Netbeans 8.0 + JDK 1.7.0_51):

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
    JFrame frame = new JFrame(""); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    DecimalFormatSymbols symbols = new DecimalFormatSymbols(); 
    symbols.setDecimalSeparator('.'); 
    symbols.setGroupingSeparator(' '); 
    symbols.setCurrencySymbol("EUR"); 

    DecimalFormat format = new DecimalFormat("¤ #,##0.00", symbols); 
    format.setMaximumFractionDigits(2); 
    format.setGroupingUsed(true); 

    NumberFormatter formatter = new NumberFormatter(format); 
    formatter.setMinimum( 0.00); 
    formatter.setMaximum(9_999.99); 
    formatter.setAllowsInvalid(false); 
    formatter.setOverwriteMode(true); 

    JFormattedTextField field = new JFormattedTextField(formatter); 
    field.setColumns(10); 
    field.setValue(0.33); 

    frame.add(field); 
    frame.pack(); 
    frame.setVisible(true); 
    frame.setLocationRelativeTo(null); 

Что я ожидаю:

// Step    Text in TextField 
    // 1: GUI started EUR <caret>0.33 
    // 2: '1' pressed EUR 1<caret>.33 
    // 3: '2' pressed EUR 12<caret>.33 

Что я получаю:

// Step    Text in TextField 
    // 1: start GUI EUR <caret>0.33  [OK] 
    // 2: press '1' EUR 1<caret>.33  [OK] 
    // 3: press '2' EUR 1 2<caret>33.00 [NOK, see expected result above] 

Мне кажется, что Formatter делает (для шага 3):

  • вставка '2' в позиции курсора -> EUR 12,33
  • удалить все 'Форматирование символов' -> 1233
  • форматирует результат "снятия" снова -> EUR 1 233,00

Это поведение по умолчанию для NumberFormatter? Если да, я что-то упустил в настройке форматирования или мне нужно написать свой собственный? Если нет, что я делаю неправильно?

С уважением,

Xan.

+0

2 перезаписывает десятичную точку, вызывая переформатирование. –

+0

whats, is set, test the Locale, – mKorbel

+0

@Joop О, ты прав. Почему я не подумал об этом ?! Любая идея, как я мог бы предотвратить переопределение десятичной точки (но разрешить переопределение для цифр)? – Xan

ответ

2
  • кажется, так как я не являюсь, описанный вопрос, чтобы проверить настройки для InputVerifier as is described in API,

  • Я предлагаю использовать простой JTextField с DocumentFilter и название ISO для валюты по отношению к обертывание с использованием NavigationFilter, e.g. excelent code example by camickr

.

import java.awt.*; 
import java.math.*; 
import java.text.*; 
import javax.swing.*; 
import javax.swing.JFormattedTextField.AbstractFormatter; 
import javax.swing.JFormattedTextField.AbstractFormatterFactory; 
import javax.swing.text.InternationalFormatter; 

public class DocumentListenerAdapter { 

    public DocumentListenerAdapter() { 
     JFrame frame = new JFrame("AbstractTextField Test"); 
     final JFormattedTextField textField1 = new JFormattedTextField(new Float(10.01)); 
     textField1.setFormatterFactory(new AbstractFormatterFactory() { 
      @Override 
      public AbstractFormatter getFormatter(JFormattedTextField tf) { 

       DecimalFormatSymbols symbols = new DecimalFormatSymbols(); 
       symbols.setDecimalSeparator('.'); 
       symbols.setGroupingSeparator(' '); 
       symbols.setCurrencySymbol("EUR"); 

       DecimalFormat format = new DecimalFormat("¤ #,##0.00", symbols); 
       format.setMaximumFractionDigits(2); 
       format.setGroupingUsed(true); 

       //NumberFormat format = DecimalFormat.getInstance(); 
       format.setMinimumFractionDigits(2); 
       format.setMaximumFractionDigits(2); 
       format.setRoundingMode(RoundingMode.HALF_UP); 
       InternationalFormatter formatter = new InternationalFormatter(format); 
       formatter.setAllowsInvalid(false); 
       formatter.setMinimum(0.0); 
       formatter.setMaximum(9000.00); 
       return formatter; 
      } 
     }); 
     NumberFormat numberFormat = NumberFormat.getNumberInstance(); 
     numberFormat.setMaximumFractionDigits(2); 
     numberFormat.setMaximumFractionDigits(2); 
     numberFormat.setRoundingMode(RoundingMode.HALF_UP); 
     final JFormattedTextField textField2 = new JFormattedTextField(numberFormat); 
     textField2.setValue(new Float(10.01)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(textField1, BorderLayout.NORTH); 
     frame.add(textField2, BorderLayout.SOUTH); 
     frame.setVisible(true); 
     frame.pack(); 
    } 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new DocumentListenerAdapter(); 
      } 
     }); 
    } 
} 
Смежные вопросы