JTextField принимает в два раза больше информации, но почему? - PullRequest
0 голосов
/ 01 сентября 2018

Я хочу сделать программируемый калькулятор, у меня есть базовый графический интерфейс, и теперь я пытаюсь настроить кнопки и дисплей. Мой отображаемый текст будет в основном «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 голосов
/ 03 сентября 2018

Вот простое решение:

Если вы используете 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) {
        }

    });
0 голосов
/ 01 сентября 2018

Для этого я получаю 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,

  • Первый аргумент - сам JTextField.
  • Второй аргумент (10) - максимальная длина ввода, Вы можете ввести только цифру.
...