【问题标题】:JTextField accept only valid unsigned Shorts? (Using KeyAdapter)JTextField 只接受有效的未签名短裤? (使用 KeyAdapter)
【发布时间】:2012-08-11 22:03:41
【问题描述】:

下面是我试图开始工作以仅接受小于 65535 的值的 KeyAdapter。似乎它在实际应该的位置后面敲击了一个键。例如,如果我输入“55”,System.out.println 将产生“5”,执行“3298”将产生“329”,等等。

// Allows for unsigned short values only
KeyAdapter unsignedShortAdapter = new KeyAdapter() {

    public void keyTyped(KeyEvent e) {
        char c = e.getKeyChar();
        int tempInt = 0;
        JTextField temp = null;

        if (!((Character.isDigit(c) || (c == KeyEvent.VK_BACK_SPACE) || (c == KeyEvent.VK_DELETE)))) {
            getToolkit().beep();
            e.consume();
        }
        try {
            temp = (JTextField) e.getSource();
            System.out.println(temp.getText());
            tempInt = (Integer.parseInt(temp.getText().toString()));
        } catch (NumberFormatException e1) {

        } finally {
            if (tempInt > (Short.MAX_VALUE * 2)) {
                 getToolkit().beep();
                 e.consume();
                temp.setText(temp.getText().substring(0, temp.getText().length() - 1));

                invalidate();
            }

        }
    }

};

【问题讨论】:

  • 你必须使用KeyListener吗?因为否则有很多更好的解决方案
  • 不,我不知道。我想用我能得到的任何东西,哈哈。我只是使用 KeyListener 来防止用户输入非数字字符。
  • 问题是,您在文本字段更新之前获得了击键,因此当您的文本字段包含“5”并且您按“5”时,该字段仅包含“5”你捕获击键。
  • 是的,不过我不知道如何解决。
  • 为此我会使用JSpinnerSpinnerNumberModel

标签: java swing adapter jtextfield short


【解决方案1】:

因此,我们应该使用 DocumentFilter,而不是您发现的 KeyListener,它不可靠并且会导致许多令人讨厌的副作用(以及可能的文档突变异常:P),因为它就是这样专为

public class ShortFilter extends DocumentFilter {

    protected boolean valid(String text) {


        boolean valid = true;
        for (char check : text.toCharArray()) {

            if (!Character.isDigit(check)) {

                valid = false;
                break;

            }

        }

        if (valid) {

            int iValue = Integer.parseInt(text);

            valid = iValue <= (Short.MAX_VALUE * 2);

        }

        return valid;

    }

    @Override
    public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {

        StringBuilder sb = new StringBuilder(fb.getDocument().getText(0, fb.getDocument().getLength()));
        sb.insert(offset, text);

        if (valid(sb.toString())) {

            super.insertString(fb, offset, text, attr);

        }

    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

        if (length > 0) {

            StringBuilder sb = new StringBuilder(fb.getDocument().getText(0, fb.getDocument().getLength()));

            sb.delete(offset, length);
            sb.insert(offset, text);

            if (valid(sb.toString())) {

                super.replace(fb, offset, length, text, attrs);

            }

        } else {

            insertString(fb, offset, text, attrs);

        }

    }
}

您需要将此应用到该字段的文档

((AbstractDocument) field.getDocument()).setDocumentFilter(new ShortFilter());

我去看看

更多信息

小数包含更新

基本上,如果要允许包含小数,则需要在 valid 方法中允许字符。

您还需要检查当前文档的内容

StringBuilder sb = new StringBuilder(fb.getDocument().getText(0, fb.getDocument().getLength()));

// Update the StringBuilder as per noraml
// Check valid as per normal

if (text.contains(".") && sb.contains(".")) {
  // already have decimal place
} else {
  // Business as usual...
}

【讨论】:

  • 我将如何为十进制值执行此操作?基本上是问我如何将其限制为一个“。”
  • @BackpackOnHead 检查更新,我以一些非常基本的逻辑为例
猜你喜欢
  • 1970-01-01
  • 2013-12-22
  • 2021-07-24
  • 2017-09-17
  • 2016-03-26
  • 1970-01-01
  • 2013-01-16
相关资源
最近更新 更多