Reputation: 81
I know this has been asked and answered many times but I still can't get the answer that I really need. Hopefully this time, somebody can help me and I thank you in advance. :)
This is what I want in my program, I want user to limit to input only numbers. Whenever they input letters and others there will be a prompt message. I can do that, there is a prompt message for letters and other char but the inputted value still remain, I want it to be cleared.
Please see my code.
private void txtQty1KeyTyped(java.awt.event.KeyEvent evt) {
txtQty1.addKeyListener(new KeyAdapter() {});
char char_input = evt.getKeyChar();
if (((char_input < '0') || (char_input > '9')) && (char_input != '\b'))
{
JOptionPane.showMessageDialog(this, "Number only!","Invalid Input",JOptionPane.ERROR_MESSAGE);
txtQty1.setText(" ");
}
}
Though I clear my textfield, the character that I input still appears. Any help would be much appreciated. Thank you! :)
Upvotes: 1
Views: 9726
Reputation: 1592
You need to create a subclass of DocumentFilter class and use a regular expression to match each inserted string/character if they are digits or not and perform actions accordingly.
Below is a fully working sample code of this working. Thanks to @camickr for pointing out using DocumentFilter is more up-to-date than the old way of extending JTextField to achieve the same result.
import java.awt.BorderLayout;
import java.util.regex.Pattern;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class TestDocumentFilter {
public static void main(String... args) {
new TestDocumentFilter();
}
public TestDocumentFilter() {
JTextField textField = new JTextField(10);
((AbstractDocument) textField.getDocument()).setDocumentFilter(new CustomDocumentFilter());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(5, 5));
frame.getContentPane().add(textField, BorderLayout.NORTH);
frame.setSize(400, 200);
frame.setVisible(true);
}
private class CustomDocumentFilter extends DocumentFilter {
private Pattern regexCheck = Pattern.compile("[0-9]+");
@Override
public void insertString(FilterBypass fb, int offs, String str, AttributeSet a) throws BadLocationException {
if (str == null) {
return;
}
if (regexCheck.matcher(str).matches()) {
super.insertString(fb, offs, str, a);
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String str, AttributeSet attrs)
throws BadLocationException {
if (str == null) {
return;
}
if (regexCheck.matcher(str).matches()) {
fb.replace(offset, length, str, attrs);
}
}
}
}
Upvotes: 5
Reputation: 3056
Add line evt.consume()
in code as below :
JOptionPane.showMessageDialog(this, "Number only!","Invalid Input",JOptionPane.ERROR_MESSAGE);
txtQty1.setText(" ");
evt.consume(); //consume the key type event
Detail On http://docs.oracle.com/javase/7/docs/api/java/awt/event/InputEvent.html#consume()
To disable also paste wrong input in txtQty1
text field you can use caretUpdate
event as below :
Note : if you use Netbeans GUI form just create caretUpdate event.
private void txtQty1CaretUpdate(javax.swing.event.CaretEvent evt) {
String text = txtQty1.getText();
if(text != null) {
if(!text.matches("[0-9]*")) {
txtQty1.setText(" ");
}
}
}
Upvotes: 1