【问题标题】:Java : JFormattedTextField saving numbersJava : JFormattedTextField 保存数字
【发布时间】:2012-01-24 06:27:23
【问题描述】:

在我的应用程序中,我想输入特定限制的数字(数量),因此使用了 JFormattedTextField。限制如“12345678.99”,即“。”之前的 8 位数字。和 2 在“。”之后等等。这是我的实现代码,但结果不如预期。

    startBalTxt.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("########.##"))));
    startBalTxt.setText(resourceMap.getString("startBalTxt.text")); // NOI18N
    startBalTxt.setFont(Utility.getTextFont());
    startBalTxt.setName("startBalTxt"); // NOI18N

  INPUT                RESULT  
"12345678905.99"   => "12345678906"      ==> Should give "12345678.99" or "12345679.99"
"12345678.555"     => "12345678.56"      ==> CORRECT
"1234567890123456" => "1234567890123456" ==> Absolutely wrong in all aspects

我哪里错了?以及如何使它按我的预期工作。

根据 StanislavL 的建议进行更新:

    numberFormat = (DecimalFormat) DecimalFormat.getNumberInstance();
    numberFormat.setMaximumFractionDigits(2);
    numberFormat.setMaximumIntegerDigits(8);
    numberFormat.setMinimumFractionDigits(0);
    numberFormat.setMinimumIntegerDigits(2);

    nfr = new NumberFormatter(numberFormat);

    initComponents();
    myParent = parent;
    this.startBalTxt.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(nfr));

    Results ->  4562147896.45  == > 62,147,896.45

它确实遵守了限制,但它消除了以前的数字而不是以后的数字。我的意思是 4562147896.45 而不是 "45" "96" 不应该被淘汰。

【问题讨论】:

    标签: java swing number-formatting jformattedtextfield


    【解决方案1】:

    DecimalFormat 传递给JFormattedTextField 构造函数。它有以下方法

    setMaximumIntegerDigits
    setMinimumIntegerDigits
    setMaximumFractionDigits
    setMinimumFractionDigits
    

    【讨论】:

    • 其实我用的是NetBeans。无法修改构造函数。只能使用 FormatFactory 来设置它。添加了上面的代码并将结果显示在你身上。
    • @Tvd 如果有工具妨碍您,请不要使用它。至少完全了解它的所有可能性(非常肯定 - 就像猜测一样,自己永远不要使用它 - 它支持所有构造函数)
    • 可以消除数字吗 - 如底部问题所述。
    • 如何将整数位数限制为仅 8 - 8 位数后它会发出哔哔声或不允许为用户输入任何此类指示????
    【解决方案2】:

    即使JFormattedTextField 实现了DecimalFormatNumberFormat,最好还是使用DocumentListener

    1) 通过使用 DecimalFormatNumberFormat 简单的 User-non-Acceptable 通过实现 setMinimum() 和 setMaximum() 在 Big Figures 之间跳转并不好

    2) JTextComponents 默认实现插入文本,那么任何解决方法都是 User-non-Acceptable by implementsJFormattedTextFieldDecimalFormat orNumberFormat 通过实现 setMinimum() 和 setMaximum()

    3) 它非常舒适的使用DocumentListener 允许添加任何数量,但突出显示超出范围

    4) 或使用JSpinnerSpinnerNumberModel,可以将Formatter 设置为Number Instance

    InternationalFormatterDocumentListener 的示例

    import java.awt.*;
    import java.awt.font.TextAttribute;
    import java.math.*;
    import java.text.*;
    import java.util.Map;
    import javax.swing.*;
    import javax.swing.JFormattedTextField.*;
    import javax.swing.event.*;
    import javax.swing.text.InternationalFormatter;
    
    public class DocumentListenerAdapter {
    
        public static void main(String args[]) {
            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) {
                    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(1000.00);
                    return formatter;
                }
            });
            final Map attributes = (new Font("Serif", Font.BOLD, 16)).getAttributes();
            attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
            final JFormattedTextField textField2 = new JFormattedTextField(new Float(10.01));
            textField2.setFormatterFactory(new AbstractFormatterFactory() {
    
                @Override
                public AbstractFormatter getFormatter(JFormattedTextField tf) {
                    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(1000.00);
                    return formatter;
                }
            });
            textField2.getDocument().addDocumentListener(new DocumentListener() {
    
                @Override
                public void changedUpdate(DocumentEvent documentEvent) {
                    printIt(documentEvent);
                }
    
                @Override
                public void insertUpdate(DocumentEvent documentEvent) {
                    printIt(documentEvent);
                }
    
                @Override
                public void removeUpdate(DocumentEvent documentEvent) {
                    printIt(documentEvent);
                }
    
                private void printIt(DocumentEvent documentEvent) {
                    DocumentEvent.EventType type = documentEvent.getType();
                    double t1a1 = (((Number) textField2.getValue()).doubleValue());
                    if (t1a1 > 1000) {
                        Runnable doRun = new Runnable() {
    
                            @Override
                            public void run() {
                                textField2.setFont(new Font(attributes));
                                textField2.setForeground(Color.red);
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    } else {
                        Runnable doRun = new Runnable() {
    
                            @Override
                            public void run() {
                                textField2.setFont(new Font("Serif", Font.BOLD, 16));
                                textField2.setForeground(Color.black);
                            }
                        };
                        SwingUtilities.invokeLater(doRun);
                    }
                }
            });
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(textField1, BorderLayout.NORTH);
            frame.add(textField2, BorderLayout.SOUTH);
            frame.setVisible(true);
            frame.pack();
        }
    
        private DocumentListenerAdapter() {
        }
    }
    

    【讨论】:

    • 很好的例子。我没有得到你的第一点 - 为什么 User-non-accepteble ?在为上述问题寻找解决方案时,我读过很多次开发人员说,将 DocumentListener 用于此类任务并不好,而应该只使用格式化程序。我能找到的一个原因是 DocumentListenr 在我们从该文本字段移动后显示结果,而格式化程序只会在现场显示。你能说明一下吗?
    • @Tvd 我忘了在我的答案中添加 setMinimum() 和 setMaximum(),没有关于开发人员喜欢或 wharever,关于 user_freindyl,真的在分配的位置内移动是可怕的,
    • 如果我将 setMinimum 和 setMaximum 添加到 textfield2 的格式化程序,则 DocumentListener 的 printIt() 永远不会处于活动状态。即使我尝试进行复制粘贴,格式化程序也只会注意并且不允许粘贴无效数据。如果我必须实现格式化程序和 DocumentListener(就像对 textfield2 所做的那样)并且格式化程序只查找大部分,那么 DocumentListener 出现在哪里和何时出现在图片下方??
    • 对,但是当您使用 Focus 或 stackoverflow.com/questions/7378821/jformattedtextfield-issues 触及限制时会出现问题
    • 对@mKorbel。感谢您的澄清。是的,我有另一个 formattedtextField 我在其中设置了 Mask 并且在该字段中我看到了您在上面的链接中所说的内容。我尝试添加 DocumentListner,如您的查询中所示。但是在我只有 JFT 的情况下,无法实现垃圾测试的解决方案。你能展示一些指导方针吗?非常感谢。 ——
    猜你喜欢
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2010-09-09
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多