JTextField需要两倍的输入,但为什么呢?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JTextField需要两倍的输入,但为什么呢?相关的知识,希望对你有一定的参考价值。

我想制作一个可编程计算器,我得到了基本的GUI,现在我正在尝试设置按钮和显示器。我的显示文本基本上是“0”,如果用户键入数字,则应显示该数字。我尝试使用KeyListener,但如果我按一个键,它将显示两次键。为什么?

 textField.addKeyListener(new KeyListener()
        boolean newNumber = true;

        public void keyTyped(KeyEvent e) 
        

        public void keyPressed(KeyEvent e) 
            int keyCode = e.getKeyCode();


            if(keyCode == e.VK_BACK_SPACE && textField.getText().length() == 1)
                textField.setText("0");
                newNumber = true;
                

            if(textField.getText().equals("0") && newNumber)
                textField.setText(KeyEvent.getKeyText(keyCode));
                newNumber = false;
            
        

        public void keyReleased(KeyEvent e) 
        

    );

输入之前:

enter image description here

输入“1”后:

enter image description here

答案

一个简单的解决方案:

如果你使用keyPressed,你必须在keyReleased做一些事情,这变得复杂。 keyTyped是一种更简单的方式。

您可以使用e.consume()来防止插入双位数。

    textField.addKeyListener(new KeyListener() 

        int codeDelete = KeyEvent.getExtendedKeyCodeForChar(KeyEvent.VK_DELETE);
        int codeBackSpace = KeyEvent.getExtendedKeyCodeForChar(KeyEvent.VK_BACK_SPACE);

        @Override
        public void keyTyped(KeyEvent e) 

            char keyChar = e.getKeyChar();

            if (textField.getText().length() == 0) 
                textField.setText("0");
            
            else if (textField.getText().equals("0") && keyChar != codeDelete && keyChar != codeBackSpace) 
                textField.setText(String.valueOf(e.getKeyChar()));
                e.consume();
            
        

        @Override
        public void keyPressed(KeyEvent e) 
        

        @Override
        public void keyReleased(KeyEvent e) 
        

    );
另一答案

为此,我像这样派生PlainDocument:

import java.awt.EventQueue;
import java.util.regex.Pattern;

import javax.swing.JTextField;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class DigitDocument extends PlainDocument 

    private static final long       serialVersionUID    = 1L;
    protected static final Pattern  patternStartZero    = Pattern.compile("^0.+");

    protected final JTextField      textField;

    private final int               limit;
    private final Runnable          runnableFormat;

    public DigitDocument(JTextField textField, int limit) 

        super();

        this.textField = textField;
        this.limit = limit;

        runnableFormat = new Runnable() 

            @Override
            public void run() 

                String text = textField.getText();

                if (text.length() == 0) 
                    textField.setText("0");
                
                else if (patternStartZero.matcher(text).matches()) 
                    textField.setText(text.replaceAll("^0+", ""));
                
            
        ;
    

    @Override
    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException 

        str = str.replaceAll("[^0-9]", "");

        if (str.length() == 0)
            return;

        else if ((getLength() + str.length()) <= limit)
            super.insertString(offset, str, attr);

        EventQueue.invokeLater(runnableFormat);
    

    @Override
    public void remove(int offs, int len) throws BadLocationException 
        if (!"0".equals(textField.getText()))
            super.remove(offs, len);

        EventQueue.invokeLater(runnableFormat);
    

用法是:

textField.setDocument(new DigitDocument(textField, 10));
textField.setText("0");

在DigitDocument中,

  • 第一个arg是JTextField本人。
  • 第二个arg(10)是最大输入长度,您只能输入数字。

以上是关于JTextField需要两倍的输入,但为什么呢?的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode:至少是其他数字两倍的最大数747

747. 至少是其他数字两倍的最大数

LeetCode747 至少是其他数字两倍的最大数

《LeetCode之每日一题》:265.至少是其他数字两倍的最大数

747.至少是其他数字两倍的最大数Easy

288至少是其他数字两倍的最大数