JTextField接受两倍的输入,但是为什么呢?

时间:2018-09-01 10:33:24

标签: java swing jtextfield keylistener

我想做一个可编程计算器,我有基本的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

2 个答案:

答案 0 :(得分:2)

这是一个简单的解决方案:

如果您使用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) {
        }

    });

答案 1 :(得分:1)

为此,我像这样派生 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)是最大输入长度, 您只能输入数字。