尝试处理减号键时自定义 JTextField 错误

Custom JTextField bug when trying to process minus key

我自定义了 JTextField 来输入数值。 class 如下所示:

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;

public class JNumberField extends JTextField {

    public JNumberField(int width, int height) {
        this();
        setPreferredSize(new Dimension(width, height));
    }

    public JNumberField() {
        setFont(new Font("Monospace", Font.BOLD, 23));
        setHorizontalAlignment(JTextField.HORIZONTAL);
    }

    @Override
    public void processKeyEvent(KeyEvent ev) {
        //Accepts digits, backspace, minus key and left/right arrow keys
        if (Character.isDigit(ev.getKeyChar()) || ev.getKeyCode() == KeyEvent.VK_BACK_SPACE || ev.getKeyCode() == KeyEvent.VK_MINUS || ev.getKeyCode() == KeyEvent.VK_LEFT || ev.getKeyCode() == KeyEvent.VK_RIGHT) {
            super.processKeyEvent(ev);
        }
        ev.consume();
    }

    public static void main(String[] args) {
        JOptionPane.showInputDialog(new JNumberField(300,50));
    }
}

除“-”键外,所有键都可以使用。我还打印了按下的键码,它以 45 响应,因此执行了 if 语句,但它没有将 - 插入文本字段。这是一个错误还是如何修复?我还尝试删除 if 语句并调用 processKeyEvent 方法,然后它可以插入 - 符号...

首先我完全同意安德鲁的观点,有更好的方法来解决问题。例如你可以使用:

  1. 一个JSpinner
  2. 一个JFormattedTextField
  3. a DocumentFilter - 参见:

上述解决方案更好的原因是:

  1. 您不需要扩展 class
  2. 解决方案更抽象

您的解决方案是低级解决方案,这意味着您需要了解按下某个键时生成的事件以及 Swing 如何处理这些事件。

更抽象的解决方案总是更好,因为您不需要了解细节。这就是 Swing API 进化的原因。

在您的情况下,您没有理解“可显示”键事件和“不可显示”事件之间的区别。

在生成 keyTyped 事件时更新文本组件,该事件仅为“数字”和“-”等“可显示”字符生成。

使用箭头键或退格键不会生成“keyTyped”事件。

因此您需要更改逻辑以将“-”作为字符(而不是键码)处理:

//if (Character.isDigit(ev.getKeyChar()) || ev.getKeyCode() == KeyEvent.VK_MINUS ...
if (Character.isDigit(ev.getKeyChar()) || ev.getKeyChar() == '-' ...