Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restricting JTextField input to Integers [duplicate]

I know that this question must have been asked and answered a million times, but I just can't find an easy solution. I have a JTextField that is meant to accept only positive integers as input. I need a way to make sure that nothing else gets input here.

I already have a keyListener attached to this control. Removing the other code that this listener is there to handle, I have this:

       txtAnswer.addKeyListener(new KeyAdapter() {         @Override         public void keyPressed(KeyEvent e) {              int key = e.getKeyCode();              /* Restrict input to only integers */             if (key < 96 && key > 105) e.setKeyChar('');         };     }); 

As you can see, I'm trying to use the the KeyCode to check whether the key just pressed falls within the range of integers. This seems to work. But what I want to do is to simply disregard the entry if it falls outside of this range. The code e.setKeyChar('') was meant to handle this, but it doesn't work. The code will compile, but it has no visible effect.

Can anybody tell me if I am on the right track? What can I replace e.setKeyChar('') with to make this work? Or am I totally going in the wrong direction?

Thanks.

like image 398
AndroidDev Avatar asked Jun 19 '12 01:06

AndroidDev


People also ask

How do I allow only numbers in JTextField?

txtAnswer. addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { int key = e. getKeyCode(); /* Restrict input to only integers */ if (key < 96 && key > 105) e. setKeyChar(''); }; });

Can you enter more than one line in a JTextField?

Only one line of user response will be accepted. If multiple lines are desired, JTextArea will be needed. As with all action events, when an event listener registers an event, the event is processed and the data in the text field can be utilized in the program.

What is the function of JTextField control?

A JTextField subclass that allows you to specify the legal set of characters that the user can enter. See How to Use Formatted Text Fields.


2 Answers

Do not use a KeyListener for this as you'll miss much including pasting of text. Also a KeyListener is a very low-level construct and as such, should be avoided in Swing applications.

The solution has been described many times on SO: Use a DocumentFilter. There are several examples of this on this site, some written by me.

For example: using-documentfilter-filterbypass

Also for tutorial help, please look at: Implementing a DocumentFilter.

Edit

For instance:

import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.DocumentFilter; import javax.swing.text.PlainDocument;  public class DocFilter {    public static void main(String[] args) {       JTextField textField = new JTextField(10);        JPanel panel = new JPanel();       panel.add(textField);        PlainDocument doc = (PlainDocument) textField.getDocument();       doc.setDocumentFilter(new MyIntFilter());         JOptionPane.showMessageDialog(null, panel);    } }  class MyIntFilter extends DocumentFilter {    @Override    public void insertString(FilterBypass fb, int offset, String string,          AttributeSet attr) throws BadLocationException {        Document doc = fb.getDocument();       StringBuilder sb = new StringBuilder();       sb.append(doc.getText(0, doc.getLength()));       sb.insert(offset, string);        if (test(sb.toString())) {          super.insertString(fb, offset, string, attr);       } else {          // warn the user and don't allow the insert       }    }     private boolean test(String text) {       try {          Integer.parseInt(text);          return true;       } catch (NumberFormatException e) {          return false;       }    }     @Override    public void replace(FilterBypass fb, int offset, int length, String text,          AttributeSet attrs) throws BadLocationException {        Document doc = fb.getDocument();       StringBuilder sb = new StringBuilder();       sb.append(doc.getText(0, doc.getLength()));       sb.replace(offset, offset + length, text);        if (test(sb.toString())) {          super.replace(fb, offset, length, text, attrs);       } else {          // warn the user and don't allow the insert       }     }     @Override    public void remove(FilterBypass fb, int offset, int length)          throws BadLocationException {       Document doc = fb.getDocument();       StringBuilder sb = new StringBuilder();       sb.append(doc.getText(0, doc.getLength()));       sb.delete(offset, offset + length);        if (test(sb.toString())) {          super.remove(fb, offset, length);       } else {          // warn the user and don't allow the insert       }     } } 

Why is this important?

  • What if the user uses copy and paste to insert data into the text component? A KeyListener can miss this?
  • You appear to be desiring to check that the data can represent an int. What if they enter numeric data that doesn't fit?
  • What if you want to allow the user to later enter double data? In scientific notation?
like image 78
Hovercraft Full Of Eels Avatar answered Sep 17 '22 12:09

Hovercraft Full Of Eels


You can also use JFormattedTextField, which is much simpler to use. Example:

public static void main(String[] args) {     NumberFormat format = NumberFormat.getInstance();     NumberFormatter formatter = new NumberFormatter(format);     formatter.setValueClass(Integer.class);     formatter.setMinimum(0);     formatter.setMaximum(Integer.MAX_VALUE);     formatter.setAllowsInvalid(false);     // If you want the value to be committed on each keystroke instead of focus lost     formatter.setCommitsOnValidEdit(true);     JFormattedTextField field = new JFormattedTextField(formatter);      JOptionPane.showMessageDialog(null, field);      // getValue() always returns something valid     System.out.println(field.getValue()); } 
like image 42
Peter Tseng Avatar answered Sep 18 '22 12:09

Peter Tseng