How to restrict a JTextFiled to accept only numbers less then 10, no words, no spaces or any other special characters?
-
For starters, better use a `JFormattedTextField` with a `NumberFormat`. I don't know off the top of the head how to limit the range though... – Silly Freak Jan 18 '14 at 15:20
-
You can do this with a DocumentFilter. – Hovercraft Full Of Eels Jan 18 '14 at 15:20
-
well can't you check the length of the string that u received from the textfield and throw a warning of some sort? – user2837260 Jan 18 '14 at 15:21
-
oh dang..there is a pre defined method even for this ! – user2837260 Jan 18 '14 at 15:21
-
1Also check out my answer to a similar question [here](http://stackoverflow.com/questions/6172267/how-to-restrict-the-jtextfield-to-a-x-number-of-characters). – Hovercraft Full Of Eels Jan 18 '14 at 15:24
-
@HovercraftFullOfEels, `Then up-vote his answer because it is, as usual, clean, helpful and correct.`, normally I would agree, but as I have noted in the comments, that approach does not work for me. I did include my suggestion for a solution to this problem in the comments. – camickr Jan 18 '14 at 17:09
-
@HovercraftFullOfEels have you heard of Swing JavaBuilders? I think it's a clean solution. – AncientSwordRage Jan 18 '14 at 21:34
-
@Pureferret: no, I'm not familiar with this tool and will have to look into it. Do you have a link to its documentation? – Hovercraft Full Of Eels Jan 18 '14 at 21:52
4 Answers
The easiest would be to use a component designed for this:
JSpinner spinner = new JSpinner();
spinner.setModel(new SpinnerNumberModel(0, null, 10, 1));
Technically JSpinner is not derived from JTextField, it uses one internally for the editor part and thus looks like one (plus it has additional buttons to change the number with mouse clicks).
- 11,559
- 1
- 42
- 50
Again, a DocumentFilter is one way to solve this:
import javax.swing.*;
import javax.swing.text.*;
@SuppressWarnings("serial")
public class DocFilterExample extends JPanel{
JTextField textfield = new JTextField(5);
public DocFilterExample() {
PlainDocument doc = (PlainDocument) textfield.getDocument();
doc.setDocumentFilter(new MaxNumberDocFilter(10));
add(textfield);
}
private class MaxNumberDocFilter extends DocumentFilter {
private int maxNumber;
public MaxNumberDocFilter(int maxnumber) {
this.maxNumber = maxnumber;
}
private boolean verifyText(String text) {
if (text.isEmpty()) {
return true; // allow for a blank text field
}
int value = 0;
try {
value = Integer.parseInt(text);
if (value >= 0 && value < maxNumber) {
return true; // if it's a number in range, it passes
}
} catch (NumberFormatException e) {
return false; // if it's not a number, it fails.
}
return false;
}
@Override
public void insertString(FilterBypass fb, int offset, String string,
AttributeSet attr) throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.insert(offset, string);
if (verifyText(sb.toString())) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.replace(offset, offset + length, text);
if (verifyText(sb.toString())) {
super.replace(fb, offset, length, text, attrs);
}
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
Document doc = fb.getDocument();
String oldText = doc.getText(0, doc.getLength());
StringBuilder sb = new StringBuilder(oldText);
sb.replace(offset, offset + length, "");
if (verifyText(sb.toString())) {
super.remove(fb, offset, length);
}
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Eg");
frame.getContentPane().add(new DocFilterExample());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
- Advantages:
- no error messages are needed. Instead it simply prevents input of bad input.
- It works for cut and paste just fine.
- Disadvantages:
- no error messages are given, and so the user won't know why his text is not accepted.
- it's a bit long and bulky.
- it's not easy "chaining" -- using multiple filters at once, something Rob Camick has done some work on.
- 283,665
- 25
- 256
- 373
Try This :-
JTextField textField = new JTextField();
textField.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
//do stuff here when enter pressed
String text = textField.getText();
if(text!=null && !text.equals("")){
char c = evt.getKeyChar();
int val=Integer.parseInt(c);
if(val>=48 && val<=57){
if(Integer.parseInt(text)<=10){
//Its valid and allowed
}else{
//Its invalid, show error message here
}
}else{
//Show message only numbers are allowed
return false;
}
}
}
});
Hope it will help you.
- 6,239
- 12
- 46
- 64
-
An `ActrionListener` will only be fired when the enter key is pressed. Either of the other answers provides a better solution here. – Andrew Thompson Jan 18 '14 at 21:37
Use Swing Javabuilders, where you can define your GUI in YML (below), including Text Field validation.
You declare in your gui in a yaml file, here is an example for Person.java, called Person.Yaml:
JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose):
- JButton(name=save, text=button.save, onAction=[$validate,save,done])
- JButton(name=cancel, text=button.cancel, onAction=[$confirm,cancel])
- MigLayout: |
[pref] [grow,100] [pref] [grow,100]
"label.firstName" txtFirstName "label.lastName" txtLastName
"label.email" txtEmail+*
>save+*=1,cancel=1
bind:
- txtFirstName.text: person.firstName
- txtLastName.text: person.lastName
- txtEmail.text: person.emailAddress
validate:
- txtFirstName.text: {mandatory: true, label: label.firstName}
- txtLastName.text: {mandatory: true, label: label.lastName}
- txtEmail.text: {mandatory: true, emailAddress: true, label: label.email}
The three blocks above are as follows:
The Swing Classes (JFrame, and JButton) as well as the Layout Manager, with embedded JLabels (label.firstName and label.lastName) which are recognised by the 'label' part of their declaration and the JTextFields (txtLastName,txtFirstName and txtEmail ) which are recognised by the txt part of their name.
The Data Binding: This binds JTextArea.text to class.fieldName so that when data is entered into the JTextField it is mapped to the fields.
Validation: Here is where the text is validated. Notice that the JButton with the name Save has in the onAction section has the entry $validate which runs the in-built validate method. This reads the kind of validation in from the validate block:
txtFirstName.text: {mandatory: true, label: label.firstName}
Which declares the field has to be filled in (mandatory: true) and txtEmail must be filled with a valid email address (emailAddress: true). More validation is outlined below.
Once you've declared the GUI, you just run it like so, from within your java file.
private BuildResult result;
.....
public methodName(){
.....
result = SwingJavaBuilder.build(this).setVisible(true);
}
This method (build(this)) references a .yml file of the same name (so your gui is in person.yml and is paired with person.java).
There's more validation available in the documentation :
validate:
- mandatory.text: {label: Mandatory Field, mandatory: true}
- date.text: {label: Date Field, dateFormat: "yyyy/mm/dd"}
- email.text: {label: E-Mail, email: true}
- minmax.text: {label: Min/Max Length, minLength: 5, maxLength: 10}
- regex.text: {label: Regex, regex: "[a-zA-Z0-9]+"}
- regex2.text: {label: Regex, regex: "[a-zA-Z0-9]+",
regexMessage: "''{0}'' must be a number or letter"}
- long.text: {label: Min/Max Long, minValue: 5, maxValue: 50, mandatory: true}
So you would want to use the last one long.text with this specification:
myValidNumberField{label: Number less than ten, maxValue: 10, mandatory: true}`
There's more information on the github page, about setting your GUI up like this.
- 7,086
- 19
- 90
- 173
-
For those who can't wait, here is an article that highlights the usage: http://java.dzone.com/articles/making-gui-builders-obsolete – AncientSwordRage Jan 18 '14 at 15:39
-
did you drinking, please re_read your post here, description came from my mind – mKorbel Jan 18 '14 at 20:31
-
@mKorbel I'm not sure what you're saying, but I've added more to the answer. – AncientSwordRage Jan 18 '14 at 21:29