9

我有一个文本字段,我只接受来自键盘的数字,但现在我必须更改它,因为它是一个“价格文本字段”,我还需要接受一个点“。” 适用于任何价格。

我怎样才能改变它以获得我需要的东西?

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();
                }
            }
        });
4

14 回答 14

15

正如 Oracle 建议的那样,使用格式化文本字段

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

amountFormat = NumberFormat.getNumberInstance();
...
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);
于 2013-08-06T15:16:35.930 回答
7

我只是使用try-catch块:

try {// if is number
    Integer.parseInt(String);
} catch (NumberFormatException e) {
    // else then do blah
}
于 2014-09-06T09:23:51.463 回答
6

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;
    }
}
于 2015-04-21T12:19:31.203 回答
3

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

其次,您没有过滤掉修饰符。如果用户在此字段中尝试通过键入 control-s 来保存他们的工作,则您的键侦听器将使用该事件。如果您的应用程序为某个操作分配了一个 control-5 或 alt-5 快捷方式,则此 KeyListener 将在他们键入时将 5 添加到该字段,即使用户没有尝试键入字符。您确实发现您需要传递退格键,但这并不是您需要传递的全部内容。你的方向键不起作用。您的功能键也不会。您可以解决所有这些问题,但这开始需要大量工作。

还有第三个缺点,但它只有在您将应用程序调整为外国字母时才会出现,特别是需要多次击键才能生成单个字符的应用程序,例如中文。这些字母表使 KeyListeners 无用。

麻烦就在于此。您需要过滤字符,但 KeyListener 与字符无关,它们与击键有关,这不是一回事:并非所有击键都会生成字符,也不是所有字符都是由击键生成的。您需要一种方法来查看生成后的字符,并且在修改的击键已经被过滤掉之后。

最简单的方法是使用 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()

这更快、更简洁,并且适用于外国编号系统。我也不需要您对退格字符 '\b' 进行测试。我猜你的第一个 KeyListener 过滤掉了退格键,这是你第一个线索,这是错误的方法。

在不相关的说明中,不要对组件位置进行硬编码。了解如何使用 LayoutManager。它们易于使用,并且它们将使您的代码更易于维护。

于 2016-11-21T01:56:37.797 回答
2

JTextField在java中输入双数

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();
        }
    }
}
于 2015-04-16T18:50:38.467 回答
2

你看过 JFormattedTextField 吗?它似乎做了你想要的。

于 2013-08-06T15:16:23.577 回答
1

这段代码;

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

决定是否消费关键事件。您需要更新条件,使其不消耗点字符。

于 2013-08-06T15:18:20.137 回答
1

只需右键单击 TextField / events / key / keytyped

if(!Character.isDigit(evt.getKeyChar())){
            evt.consume();}
于 2019-04-15T04:48:14.003 回答
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 文档指南。

于 2017-06-01T10:07:40.313 回答
0

也许可以帮助您过滤键入的数字和点

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();
      }
 }
于 2016-08-16T08:09:51.957 回答
0

/////////////

    JTextField ptoMinimoField = new JTextField();
    ptoMinimoField.addKeyListener(new KeyAdapter() {
        public void keyTyped(KeyEvent e) {
             boolean ret = true;
                try {

                    Double.parseDouble(ptoMinimoField.getText()+e.getKeyChar());
                }catch (NumberFormatException ee) {
                    ret = false;
                }


            if (!ret) {
                e.consume();
            }
        }
    });
于 2015-08-26T04:46:31.693 回答
-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();
                    }
                }
            });
于 2013-12-01T15:38:26.777 回答
-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();
        }
    }
}
于 2018-02-15T09:05:25.433 回答
-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();
        }
    }
})

这是迄今为止我发现的最简单的方法,并且它可以正常工作

于 2019-02-14T15:20:21.207 回答