How to allow introducing only digits in jTextField?
-
13-11-2019 - |
Question
I have tried to use the example shown here but java showing error message of
"AttributeSet cannot be resolved to a type"
That is why I am trying to use another method of allowing only digits:
txtUsername.addKeyListener(new MyKeyListener());
public class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent ke){
System.out.println("Key pressed code = "+ke.getKeyCode());
if (ke.getKeyCode()>=48 && ke.getKeyCode()<=57)
return true;
else
return false;
}
}
But of course it is not working because keyPressed
method is void
. So, what to do in order to print only digits in textfield?
Solution
Here check this code snippet, that's how you allow only digits in JTextField, by using DocumentFilter, as the most effeciive way :
import java.awt.*;
import javax.swing.*;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.DocumentFilter.FilterBypass;
public class InputInteger
{
private JTextField tField;
private MyDocumentFilter documentFilter;
private void displayGUI()
{
JFrame frame = new JFrame("Input Integer Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
tField = new JTextField(10);
((AbstractDocument)tField.getDocument()).setDocumentFilter(
new MyDocumentFilter());
contentPane.add(tField);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
@Override
public void run()
{
new InputInteger().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class MyDocumentFilter extends DocumentFilter
{
@Override
public void insertString(DocumentFilter.FilterBypass fp
, int offset, String string, AttributeSet aset)
throws BadLocationException
{
int len = string.length();
boolean isValidInteger = true;
for (int i = 0; i < len; i++)
{
if (!Character.isDigit(string.charAt(i)))
{
isValidInteger = false;
break;
}
}
if (isValidInteger)
super.insertString(fp, offset, string, aset);
else
Toolkit.getDefaultToolkit().beep();
}
@Override
public void replace(DocumentFilter.FilterBypass fp, int offset
, int length, String string, AttributeSet aset)
throws BadLocationException
{
int len = string.length();
boolean isValidInteger = true;
for (int i = 0; i < len; i++)
{
if (!Character.isDigit(string.charAt(i)))
{
isValidInteger = false;
break;
}
}
if (isValidInteger)
super.replace(fp, offset, length, string, aset);
else
Toolkit.getDefaultToolkit().beep();
}
}
Or one can simply use this approach, as given by @Carlos Heuberger
@Override
public void insertString(FilterBypass fb, int off
, String str, AttributeSet attr)
throws BadLocationException
{
// remove non-digits
fb.insertString(off, str.replaceAll("\\D++", ""), attr);
}
@Override
public void replace(FilterBypass fb, int off
, int len, String str, AttributeSet attr)
throws BadLocationException
{
// remove non-digits
fb.replace(off, len, str.replaceAll("\\D++", ""), attr);
}
OTHER TIPS
I'd suggest using a JFormattedTextField, Here is how : How to Use Formatted Text Fields
Try this:
public void replace(DocumentFilter.FilterBypass fb, int offset,
int length, String text, AttributeSet attrs)throws BadLocationException {
if(fb.getDocument().getLength() + text.length() > 10) {
return;
}
fb.insertString(offset, text, attrs);
}
instead of:
public void replace(DocumentFilter.FilterBypass fp, int offset
, int length, String string, AttributeSet aset)
throws BadLocationException
{
int len = string.length();
boolean isValidInteger = true;
for (int i = 0; i < len; i++)
{
if (!Character.isDigit(string.charAt(i)))
{
isValidInteger = false;
break;
}
}
if (isValidInteger)
super.replace(fp, offset, length, string, aset);
else
Toolkit.getDefaultToolkit().beep();
}
This is what I use to consume non-numbers
textField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
char c = e.getKeyChar();
if (((c < '0') || (c > '9')) && (c != KeyEvent.VK_BACK_SPACE)) {
e.consume(); // consume non-numbers
}
}
});
My version which rejects unwanted characters completely(I tried):
val2 = new JTextField();
val2.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
try {
char input = e.getKeyChar(); //checks each key pressed
// in other words it prevents input of any character other than 0-9 or .
try {
int i = Integer.parseInt(val2.getText());
valid1.setText(""); //valid1 is a label for the message
} catch (Exception e2) {
// TODO: handle exception
valid1.setText("Invalid Number!");
}
if((!Character.isDigit(input)) && !(input == '.')) { //numbers accept "."
e.consume();
// event won't be sent for any further event listeners
try {
int i = Integer.parseInt(val2.getText()); // checks if the string can be converted to int
double i1 = Double.parseDouble(val2.getText()); // checks if string can be converted to double
valid1.setText("");
} catch (Exception e2) {
// TODO: handle exception
// if it is not in a valid format.. it will generate error message
valid1.setText("Invalid Number!");
}
}
else {
// if format and characters are fine... no output
valid1.setText("");
}
}
catch (Exception e2) {
// TODO: handle exception
// for unexpected errors
valid1.setText("Error");
}
}
});
// auto generated for design of the textfield
val2.setColumns(10);
val2.setBounds(236, 11, 126, 43);
panel.add(val2);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow