在 Java TextField 中只接受数字和一个点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18084104/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accept only numbers and a dot in Java TextField
提问by Agustín
I've got one textField where I only accept numbers from the keyboard, but now I have to change it as it's a "price textField" and I would also need to accept a dot "." for any kind of prices.
我有一个 textField,我只接受来自键盘的数字,但现在我必须更改它,因为它是一个“价格 textField”,我还需要接受一个点“。” 对于任何价格。
How can I change this in order to get what I need?
我怎样才能改变它以获得我需要的东西?
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();
}
}
});
采纳答案by Suresh Atta
As suggested by Oracle ,Use Formatted Text Fields
按照 Oracle 的建议,使用格式化文本字段
Formatted text fields provide a way for developers to specify the valid set of characters that can be typed in a text field.
格式化文本字段为开发人员提供了一种指定可在文本字段中键入的有效字符集的方法。
amountFormat = NumberFormat.getNumberInstance();
...
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);
回答by arcy
Have you looked at a JFormattedTextField? It would seem it does what you want.
你看过 JFormattedTextField 吗?它似乎可以满足您的需求。
回答by Qwerky
This bit of code;
这段代码;
if (((caracter < '0') || (caracter > '9'))
&& (caracter != '\b')) {
decides whether to consume the key event. You need to update the condition so it doesn't consume the dot character.
决定是否消费key事件。您需要更新条件,使其不消耗点字符。
回答by Abdellah Benhammou
I have been using this solution, it's simple and efficient:
我一直在使用这个解决方案,它简单高效:
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();
}
}
});
回答by Brayan Byrdsong
I just use a try
-catch
block:
我只使用try
-catch
块:
try {// if is number
Integer.parseInt(String);
} catch (NumberFormatException e) {
// else then do blah
}
回答by V? Trung S?n
Enter the double number of JTextField
in java
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();
}
}
}
回答by Wender
JTextField txField = new DoubleJTextField();
JTextField txField = new DoubleJTextField();
Create a file DoubleJTextField.java and be happy
创建一个文件 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;
}
}
回答by Alireza Ravandi
/////////////
/////////////
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();
}
}
});
回答by irbef
maybe can help you for filtering keytyped just number and 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();
}
}
回答by MiguelMunoz
Don't ever use a KeyListener for this. Your code above has two serious bugs, both caused by the use of a KeyListener. First, it will miss any text that gets pasted in. Whenever I find a field that filters out non-digits, I always try to paste in some text, just for fun. Nine times out of ten, the text gets accepted, because they used a key listener.
永远不要为此使用 KeyListener 。您上面的代码有两个严重的错误,都是由使用 KeyListener 引起的。首先,它会错过任何粘贴的文本。每当我发现一个过滤掉非数字的字段时,我总是尝试粘贴一些文本,只是为了好玩。十有八九,文本被接受,因为他们使用了一个关键的听众。
Second, you didn't filter out modifiers. If the user tries to save their work by typing control-s while they're in this field, your key listener will consume the event. And if your application assigns, say, a control-5 or alt-5 shortcut to some action, this KeyListener will add a 5 to the field when they type it, even though the user wasn't trying to type a character. You did figure out that you needed to pass the backspace key, but that's not all you need to pass. Your arrow keys won't work. Neither will your function keys. You can fix all these problems, but it starts to be a lot of work.
其次,您没有过滤掉修饰符。如果用户在此字段中尝试通过键入 control-s 来保存他们的工作,则您的键侦听器将使用该事件。而且,如果您的应用程序为某个操作分配了 control-5 或 alt-5 快捷方式,则该 KeyListener 会在他们键入时向该字段添加 5,即使用户并未尝试键入字符。您确实发现您需要传递退格键,但这并不是您需要传递的全部内容。你的箭头键不起作用。您的功能键也不会。您可以解决所有这些问题,但开始需要大量工作。
There's a third disadvantage, but it only shows up if you adapt your application to a foreign alphabet, particularly one that takes multiple keystrokes to generate a single character, like Chinese. These alphabets make KeyListeners useless.
还有第三个缺点,但只有在您使应用程序适应外国字母表时才会出现,尤其是需要多次击键才能生成单个字符的字母表,例如中文。这些字母表使 KeyListener 毫无用处。
The trouble is this. You need to filter characters, but KeyListeners aren't about characters, they're about keystrokes, which are not the same thing: Not all keystrokes generate characters, and not all characters are generated by keystrokes. You need an approach that looks at characters after they've been generated, and after modified keystrokes have already been filtered out.
麻烦是这个。您需要过滤字符,但 KeyListeners 与字符无关,它们与击键有关,它们不是一回事:并非所有的击键都会生成字符,也不是所有的字符都是由击键生成的。您需要一种在字符生成后查看字符的方法,并且在修改后的按键已经被过滤掉之后。
The simplest approach is to use a JFormattedTextField, but I've never liked that approach, because it doesn't format or filter as you type. So instead, I will use a DocumentFilter. DocumentFilters don't operate on keystrokes, they operate on the text strings as they get inserted to your JTextField's data model. Hence, all the control-keys, arrow and function keys and such don't even reach the DocumentFilter. All pasted text goes through the DocumentFilter, too. And, for languages that take three keystrokes to generate a single character, the DocumentFilter doesn't get invoked until the character is generated. Here's what it looks like:
最简单的方法是使用 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());
}
The DigitFilter class looks like this:
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 == '.';
}
}
You could write this as an inner class, but I created a separate class so you can override the accept() method to use any criteria you want. You may also notice that I don't test for digits by writing this:
您可以将其编写为内部类,但我创建了一个单独的类,以便您可以覆盖 accept() 方法以使用您想要的任何条件。您可能还会注意到,我不会通过编写以下内容来测试数字:
(c < '0') || (c > '9')
Instead, I do this:
相反,我这样做:
Character.isDigit()
This is faster, cleaner, and works with foreign numbering systems. I also don't need your test for the backspace character, '\b'. I'm guessing that your first KeyListener was filtering out the backspace key, which was your first clue that it was the wrong approach.
这更快、更干净,并且适用于外国编号系统。我也不需要您对退格字符 '\b' 的测试。我猜你的第一个 KeyListener 过滤掉了退格键,这是你的第一个线索,它是错误的方法。
And on an unrelated note, don't hard code your component positions. Learn how to use the LayoutManagers. They're easy to use, and they'll make your code much easier to maintain.
并且在一个不相关的说明中,不要对您的组件位置进行硬编码。了解如何使用 LayoutManager。它们易于使用,并且会使您的代码更易于维护。