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

问题描述 投票:1回答:2

我想制作一个可编程计算器,我得到了基本的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

java swing jtextfield keylistener
2个回答
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
投票

为此,我像这样派生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)是最大输入长度,您只能输入数字。
© www.soinside.com 2019 - 2024. All rights reserved.