【问题标题】:NumberFormatter not behaving as expectedNumberFormatter 未按预期运行
【发布时间】:2014-11-12 16:31:51
【问题描述】:

我没有找到任何 java 问题可以帮助我解决我的问题,所以我来了。

我目前正在尝试使用带有 JFormattedTextField 的 NumberFormatter 在用户输入时在 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]

对我来说,它看起来像格式化程序(对于第 3 步):

  • 在插入符号位置插入“2” -> 12.33 欧元
  • 删除所有“格式字符” -> 1233
  • 再次格式化“删除”的结果 -> 1 233.00 欧元

这是 NumberFormatter 的默认行为吗? 如果是,我是否在格式化程序的设置中遗漏了一些东西,或者我是否需要编写一个自定义的? 如果没有,我做错了什么?

问候,

Xan。

【问题讨论】:

  • 2 覆盖小数点,导致重新格式化。
  • 什么,设置,测试语言环境,
  • @Joop 哦,你是对的。我怎么没想到?!任何想法我可以如何防止这个小数点覆盖(但允许覆盖数字)?
  • 除了切换到插入模式(i.o.覆盖),并在获得焦点上预选所有文本之外,我不会知道一些简单的事情。也许是 mKorbel 的答案。

标签: java swing currency jformattedtextfield


【解决方案1】:

.

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();
            }
        });
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-28
    • 2012-02-18
    • 2018-01-18
    • 2012-06-14
    • 2019-03-03
    • 2012-09-21
    • 2014-07-19
    相关资源
    最近更新 更多