I'm trying to create a math quiz and I only want the user to be able to enter numbers whether they're negative or positive. Is there any way to do so? I've thought of using Regular Expressions but I've heard that they are bad to use. I tried using a keylistener but then what if the user pastes? I've tried parsing the string to get an integer but then the negative symbol will not work.
Any ideas?
package com.quiz.ui;
import java.awt.BorderLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class SSCCE {
private JFrame frame;
private JPanel contentPane;
private JTextField usernameField;
public static void main(String[] arguments) {
new SSCCE().construct();
}
public void construct() {
frame = new JFrame("Login");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(getContentPane());
frame.pack();
frame.setVisible(true);
}
public JPanel getContentPane() {
usernameField = new JTextField(5);
usernameField.addKeyListener(new KeyListener() {
@Override
public void keyPressed(KeyEvent arg0) {
int keyCode = arg0.getKeyCode();
if ((keyCode > 47 && keyCode < 58) || keyCode == 45) {
arg0.consume();
}
System.out.println(arg0.getKeyCode());
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
});
contentPane = new JPanel(new BorderLayout());
contentPane.add(usernameField);
return contentPane;
}
}
Use DocumentFilter:
NumberOnlyFilter.java:
import javax.swing.*;
import javax.swing.text.*;
import java.util.regex.*;
public class NumberOnlyFilter extends DocumentFilter
{
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException
{
StringBuilder sb = new StringBuilder();
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
sb.insert(offset, text);
if(!containsOnlyNumbers(sb.toString())) return;
fb.insertString(offset, text, attr);
}
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attr) throws BadLocationException
{
StringBuilder sb = new StringBuilder();
sb.append(fb.getDocument().getText(0, fb.getDocument().getLength()));
sb.replace(offset, offset + length, text);
if(!containsOnlyNumbers(sb.toString())) return;
fb.replace(offset, length, text, attr);
}
/**
* This method checks if a String contains only numbers
*/
public boolean containsOnlyNumbers(String text)
{
Pattern pattern = Pattern.compile("([+-]{0,1})?[\\d]*");
Matcher matcher = pattern.matcher(text);
boolean isMatch = matcher.matches();
return isMatch;
}
}
and then you can use it like:
((AbstractDocument)yourTxtField.getDocument()).setDocumentFilter(new NumberOnlyFilter());