当前位置: 首页 > 面试题库 >

使JFormattedTextField的行为类似于ATM输入

夏英发
2023-03-14
问题内容

我想知道是否无论如何都要使JformattedTextField或jtextField表现得像自动柜员机钱输入。我的意思是,您从右至左输入,说输入10,您需要再按2再加上0,这样它将是10.00。程序从右到左输入时会自动输入小数点?如果未输入2
0,则为.10。这可能吗?如果我想使用该字符串进行计算,该如何返回给我?我尝试了抽象格式化程序,但是效果不是很好。我想用它来输入客户收到的金额。但是要使其成为白痴证明。


问题答案:

不管插入符号位于何处,这都迫使用户始终从右侧输入文本。插入新字符后,所有先前的字符都会向左移动。格式化将根据您的格式化程序应用:

import java.awt.*;
import java.text.*;
import javax.swing.*;
import javax.swing.text.*;

public class ABMTextField extends JTextField
{
    private DecimalFormat format;
    private String decimal;

    public ABMTextField(DecimalFormat format)
    {
        this.format = format;

        decimal = Character.toString( format.getDecimalFormatSymbols().getDecimalSeparator() );

        setColumns( format.toPattern().length() );
        setHorizontalAlignment(JFormattedTextField.TRAILING);

        setText( format.format(0.0) );

        AbstractDocument doc = (AbstractDocument)getDocument();
        doc.setDocumentFilter( new ABMFilter() );
    }

    @Override
    public void setText(String text)
    {
        Number number = format.parse(text, new ParsePosition(0));

        if (number != null)
            super.setText( text );
    }

    public class ABMFilter extends DocumentFilter
    {
        public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
            throws BadLocationException
        {
            replace(fb, offs, 0, str, a);
        }

        public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
            throws BadLocationException
        {
            if ("0123456789".contains(str))
            {
                Document doc = fb.getDocument();
                StringBuilder sb = new StringBuilder( doc.getText(0, doc.getLength()) );

                int decimalOffset = sb.indexOf( decimal );

                if (decimalOffset != -1)
                {
                    sb.deleteCharAt(decimalOffset);
                    sb.insert(decimalOffset + 1, decimal);
                }

                sb.append(str);

                try
                {
                    String text = format.format( format.parse( sb.toString() ) );
                    super.replace(fb, 0, doc.getLength(), text, a);
                }
                catch(ParseException e) {}
            }
            else
                Toolkit.getDefaultToolkit().beep();
        }

        public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
            throws BadLocationException
        {
            Document doc = fb.getDocument();
            StringBuilder sb = new StringBuilder( doc.getText(0, doc.getLength()) );

            int decimalOffset = sb.indexOf( decimal );

            if (decimalOffset != -1)
            {
                sb.deleteCharAt(decimalOffset);
                sb.insert(decimalOffset - 1, decimal);
            }

            sb.deleteCharAt( sb.length() - 1) ;

            try
            {
                String text = format.format( format.parse( sb.toString() ) );
                super.replace(fb, 0, doc.getLength(), text, null);
            }
            catch(ParseException e) {}
        }
    }

    private static void createAndShowUI()
    {
        DecimalFormat format = new DecimalFormat("###,##0.00");
        ABMTextField abm = new ABMTextField( format );

        JPanel panel = new JPanel();
        panel.add( abm );

        JFrame frame = new JFrame("ABMTextField");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

如果我想使用该字符串进行计算,该如何返回给我?

您将需要创建一个方法,也许是使用format.parse(…)方法返回实际数字的getValue()。



 类似资料:
  • 问题内容: 我在Team和Player类之间有一种@OneToMany关系。我想在您的玩家之间保存一个Team对象。玩家的标识符由团队外键和列表索引组成,如下所示。我有一个这样的映射,因为我需要保存Team和您的Players同时吃饭。 所以,如果我使用以下 无论是否使用@ CollectionsOfElements,Player类都需要一个@Embeddable注释,而不是一个@Entity,这

  • 问题内容: 在我的Web应用程序中,我有一个后台服务。该服务使用Generator类,该类包含Engine类,并且配置为使用多个线程并接受GeneratorTasks。 Engine类需要很长时间进行初始化,因此理想情况下,我希望每个线程仅初始化一次。我不能仅仅使它成为一个单例实例,因为该实例不能在多个线程之间共享(它依赖于顺序处理)。不过,在完成处理任务之后,可以很好地重用实例。 我当时正在考虑

  • 当我使用命令列出所有分支时,我会看到的输出。 命令应该显示分支列表,就像对文件所做的那样。 这是我得到的输出: 如何获得git分支的默认行为?是什么导致分页输出? 我将ZSH与(其中Git没有任何内容)一起使用,我的如下所示:

  • 问题内容: 我正在寻找一种创建表单的方法,按Enter键可使焦点移至页面上的“下一个”表单元素。我一直在网上找到的解决方案是… 不幸的是,这似乎仅在IE中有效。因此,这个问题的实质是,是否有人知道适用于FF和Chrome的解决方案?另外,我宁愿不必将 onkeydown 事件添加到表单元素本身,但是如果那是唯一的方法,则必须这样做。 编辑:另外,我已经看到人们提出了这样的问题,即这不是好样式,因为

  • 我正在阅读有关流的信息,发现我们可以使用setvbuf()函数来控制流......它写的是在行缓冲模式中,当遇到换行符时流将数据发送到文件中,在无缓冲状态下没有缓冲......所以我写了以下代码...... 所以我认为,因为这些是无缓冲流,所以输入应该在我写入屏幕后立即发送到标准输出。。。但程序在写入每一行后等待我按enter键,然后屏幕上只显示输出(由于fwrite)。。。我的问题是,当这些是无

  • 问题内容: 我想使用允许用户将持续时间值输入表单。有效值样本为: 但是,我在此方面取得的成功有限。有人可以建议如何实现吗?如果也可以使用a达到此结果,我也可以。 谢谢! 如果值钱,这是我目前的尝试: 这种排序有效,除了: 我无法获取h并m显示为纯文本(我尝试转义) * 小时数已达到最大值 问题答案: 代码: