仅接受Java TextField中的数字和点

时间:2013-08-06 15:14:24

标签: java swing filter numbers textfield

我有一个textField,我只接受键盘上的数字,但现在我必须更改它,因为它是一个“价格textField”,我还需要接受一个点“。”对于任何一种价格。

如何改变这一点以获得我需要的东西?

ptoMinimoField = new JTextField();
        ptoMinimoField.setBounds(348, 177, 167, 20);
        contentPanel.add(ptoMinimoField);
        ptoMinimoField.setColumns(10);
        ptoMinimoField.addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char caracter = e.getKeyChar();
                if (((caracter < '0') || (caracter > '9'))
                        && (caracter != '\b')) {
                    e.consume();
                }
            }
        });

13 个答案:

答案 0 :(得分:11)

正如Oracle所建议的,Use Formatted Text Fields

  

格式化文本字段为开发人员提供了一种指定可在文本字段中键入的有效字符集的方法。

amountFormat = NumberFormat.getNumberInstance();
...
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);

答案 1 :(得分:5)

JTextField txField = new DoubleJTextField();

创建一个文件DoubleJTextField.java并且很开心

public class DoubleJTextField extends JTextField {
    public DoubleJTextField(){
        addKeyListener(new KeyAdapter() {
            public void keyTyped(KeyEvent e) {
                char ch = e.getKeyChar();

                if (!isNumber(ch) && !isValidSignal(ch) && !validatePoint(ch)  && ch != '\b') {
                    e.consume();
                }
            }
        });

    }

    private boolean isNumber(char ch){
        return ch >= '0' && ch <= '9';
    }

    private boolean isValidSignal(char ch){
        if( (getText() == null || "".equals(getText().trim()) ) && ch == '-'){
            return true;
        }

        return false;
    }

    private boolean validatePoint(char ch){
        if(ch != '.'){
            return false;
        }

        if(getText() == null || "".equals(getText().trim())){
            setText("0.");
            return false;
        }else if("-".equals(getText())){
            setText("-0.");
        }

        return true;
    }
}

答案 2 :(得分:4)

我只使用try - catch块:

try {// if is number
    Integer.parseInt(String);
} catch (NumberFormatException e) {
    // else then do blah
}

答案 3 :(得分:3)

不要为此使用KeyListener。上面的代码有两个严重的错误,都是由使用KeyListener引起的。首先,它会遗漏任何粘贴的文本。每当我找到一个过滤掉非数字的字段时,我总是尝试粘贴一些文本,只是为了好玩。十分之九,文本被接受,因为他们使用了一个关键的听众。

其次,你没有过滤出修饰符。如果用户尝试通过在此字段中键入control-s来保存其工作,则您的密钥监听器将使用该事件。如果您的应用程序为某个操作指定了control-5或alt-5快捷方式,则此KeyListener会在键入字段时向该字段添加5,即使用户没有尝试键入字符。你确实知道你需要传递退格键,但这并不是你需要传递的全部内容。你的箭头键不起作用。您的功能键也不会。你可以解决所有这些问题,但它开始做了很多工作。

还有第三个缺点,但只有在你的应用程序适应外国字母表时才会出现,特别是那些需要多次击键来生成单个字符的字母,如中文。这些字母表使得KeyListeners无用。

麻烦就是这个。您需要过滤字符,但KeyListeners不是关于字符,而是关于击键,这不是同一件事:并非所有击键都会生成字符,并且并非所有字符都是通过击键生成的。您需要一种在生成字符后查看字符的方法,以及已经过滤掉修改过的键击后的字符。

最简单的方法是使用JFormattedTextField,但我从不喜欢这种方法,因为它不会在您键入时进行格式化或过滤。相反,我将使用DocumentFilter。 DocumentFilters不会按键操作,当文本字符串插入到JTextField的数据模型时,它们会对文本字符串进行操作。因此,所有控制键,箭头和功能键等都不会到达DocumentFilter。所有粘贴的文本也都通过DocumentFilter。而且,对于需要三次击键才能生成单个字符的语言,DocumentFilter在生成字符之前不会被调用。这是它的样子:

    ptoMinimoField = new JTextField();
    ptoMinimoField.setBounds(348, 177, 167, 20); // Don't do this! See below.
    contentPanel.add(ptoMinimoField);
    ptoMinimoField.setColumns(10);

    PlainDocument document = (PlainDocument) ptoMinimoField.getDocument();
    document.setDocumentFilter(new DigitFilter());
}

DigitFilter类看起来像这样:

public class DigitFilter extends DocumentFilter {
    @Override
    public void insertString(FilterBypass fb, int offset, String text, 
            AttributeSet attr) throws BadLocationException {
        super.insertString(fb, offset, revise(text), attr);
    }

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

    private String revise(String text) {
        StringBuilder builder = new StringBuilder(text);
        int index = 0;
        while (index < builder.length()) {
            if (accept(builder.charAt(index))) {
                index++;
            } else {
                // Don't increment index here, or you'll skip the next character!
                builder.deleteCharAt(index);
            }
        }
        return builder.toString();
    }

    /**
     * Determine if the character should remain in the String. You may
     * override this to get any matching criteria you want. 
     * @param c The character in question
     * @return true if it's valid, false if it should be removed.
     */
    public boolean accept(final char c) {
        return Character.isDigit(c) || c == '.';
    }
}

您可以将其编写为内部类,但我创建了一个单独的类,因此您可以覆盖accept()方法以使用您想要的任何条件。您可能还会注意到我没有通过写这个来测试数字:

(c < '0') || (c > '9')

相反,我这样做:

Character.isDigit()

这更快,更清洁,并与外国编号系统配合使用。我也不需要对退格符进行测试,&#39; \ b&#39;。我猜你的第一个KeyListener正在过滤掉退格键,这是你第一个认为这是错误方法的线索。

在一个不相关的说明中,不要硬编码你的组件位置。了解如何使用LayoutManagers。它们易于使用,并且可以使您的代码更易于维护。

答案 4 :(得分:2)

你看过一个JFormattedTextField吗?看起来它可以做你想要的。

答案 5 :(得分:2)

在java中输入JTextField的双倍数

private boolean dot = false;
private void txtMarkKeyTyped(java.awt.event.KeyEvent evt) {                                 
    char vChar = evt.getKeyChar();
    if (txtMark.getText().equals(""))
        dot = false;
    if (dot == false){
        if (vChar == '.') dot = true;
        else if (!(Character.isDigit(vChar)
                || (vChar == KeyEvent.VK_BACK_SPACE)
                || (vChar == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    } else {
        if (!(Character.isDigit(vChar)
                || (vChar == KeyEvent.VK_BACK_SPACE)
                || (vChar == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    }
}

答案 6 :(得分:1)

这段代码;

if (((caracter < '0') || (caracter > '9'))
                    && (caracter != '\b')) {

决定是否使用键事件。您需要更新条件,以便它不消耗点字符。

答案 7 :(得分:1)

只需右键单击TextField /事件/键/键入的键

if(!Character.isDigit(evt.getKeyChar())){
            evt.consume();}

答案 8 :(得分:0)

也许可以帮助你过滤keytyped just number和dot

public void filterHanyaAngkaDot(java.awt.event.KeyEvent evt){
      char c = evt.getKeyChar();
      if (! ((Character.isDigit(c) ||
              (c == KeyEvent.VK_BACK_SPACE) ||
              (c == KeyEvent.VK_DELETE))
              )&& c==KeyEvent.VK_COMMA
              )
      {
          evt.consume();
      }
 }

答案 9 :(得分:0)

JTextField txtMyTextField = new JTextField();

numOnly(txtMyTextField);

public void numOnly(Object objSource){
    ((Component) objSource).addKeyListener(new KeyListener() {

        @Override
        public void keyTyped(KeyEvent e) {
            String filterStr = "0123456789.";
            char c = (char)e.getKeyChar();
            if(filterStr.indexOf(c)<0){
                e.consume();
            }
        }
        @Override
        public void keyReleased(KeyEvent e) {}

        @Override
        public void keyPressed(KeyEvent e) {}
    });
}
  

警告:此函数不遵循正确的java文档   引导。

答案 10 :(得分:-1)

我一直在使用这个解决方案,它简单而有效:

                jtextfield.addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent e) {
                    char vChar = e.getKeyChar();
                    if (!(Character.isDigit(vChar)
                            || (vChar == KeyEvent.VK_BACK_SPACE)
                            || (vChar == KeyEvent.VK_DELETE))) {
                        e.consume();
                    }
                }
            });

答案 11 :(得分:-1)

private boolean point = false;
private void txtProductCostPriceAddKeyTyped(java.awt.event.KeyEvent evt)   
{
    char Char = evt.getKeyChar();
    if (txtProductCostPriceAdd.getText().equals(""))
        point = false;
    if (point == false){
        if (Char == '.') point = true;
        else if (!(Character.isDigit(Char) || (Char == KeyEvent.VK_BACK_SPACE) || (Char == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    } else {
        if (!(Character.isDigit(Char) || (Char == KeyEvent.VK_BACK_SPACE) || (Char == KeyEvent.VK_DELETE))) {
                evt.consume();
        }
    }
}

答案 12 :(得分:-1)

JTextField textField = new JTextField();
textField.setColumns(10);

textField.addKeyListener(new KeyAdapter() {
    @Override
    public void KeyTyped(KeyEvent e) {
        if (!(e.getKeyChar() >= '0' && e.getKeyChar() <= '9')) {
            e.consume();
        }
    }
})

这是到目前为止我发现的最简单的方法,并且可以正常工作