I used JFormattedTextField withNumberFormat in this way:
-Creat a JFormattedTextField refernce
JFormattedTextField integerField;
-Create a NumberFormat refernce
NumberFormat integerFieldFormatter;
-In the constructor:
integerFieldFormatter = NumberFormat.getIntegerInstance();
integerFieldFormatter.setMaximumFractionDigits(0);
integerField = new JFormattedTextField(integerFieldFormatter );
integerField.setColumns(5);
..........
I meant to use it with integer numbers only, but when I type numbers like 1500 it is converted after losing focus to 1,500 , and exception thrown this is the first line of it:
Exception in thread "AWT-EventQueue-0"
java.lang.NumberFormatException: For input string: "1,500"
When I use JTextField instead of JFormattedTextField All integers accepted normally, But the reason why I want to use JFormattedTextField is to benefit from its input restriction advantages.
I realize this is an old question but I just stumbled upon it through the same issue. As the other answers seemed like workarounds to me, I took a closer look at the NumberFormat methods.
I found that the easiest approach would actually be to simply deactivate grouping on the NumberFormat instance:
NumberFormat integerFieldFormatter = NumberFormat.getIntegerInstance();
integerFieldFormatter.setGroupingUsed(false);
That way no group delimiters will appear in the textfield output.
Of course you will also not be able to use them for your input, but that was not intended by the question, right?
Also for an integer instance of NumberFormat you don't need to explicitly setMaximumFractionDigits(0), as that is part of what getIntegerInstance() does for you.
I discovered the solution to my problem; Here it is:
The exact problem is that when I use JFormattedTextField with NumberFormat, the JFormattedTextField adds comma ',' before any next 3 digits for example
1000 rendered as 1,000
10000 rendered as 10,000
1000000 rendered as 1,000,000
When I read an integer value from JFormattedTextField usign this line of code
int intValue = Integer.parseInt(integerField.getText());
The comma is read as part of the string; 1000 read as 1,000 and this string value cannot be converted to integer value, and so exception is thrown.
Honestly the solution is in this Answer but I will repeat it here
use str.replaceAll(",","")
int intValue = Integer.parseInt(integerField.getText().replaceAll(",", ""));
This will replace any comma charachter ',' in the returned string and will be converted normally to int as expected.
Regards
You can do it in (at least) 2 ways:
Using a keyListener
Using DocumentFilter
if you want to use KeyListener:
KeyListener listener = new KeyAdapter(){
public void keyTyped(KeyEvent e){
if(e.getKeyCode()<KeyEvent.VK_0||e.getKeyCode()>KeyEvent.VK_9{//input<'0' or input>'9'?
e.consume();//delete the typed char
}
}
}
yourTextField.addKeyListener(listener);
to use the DocumentFilter check this link: How to allow introducing only digits in jTextField?
EDIT: i forgot to say this. As MadProgrammer said in the first comment to this answer, KeyListener is not the proper way to do it, because
You do not know in what order KeyListeners will be notified of the event and the key may have already gone to the text component before it reaches you (or it could have been consumed before it reaches you)
EDIT #2: ANOTHER QUICK WAY
MaskFormatter formatter = new MaskFormatter("#####");
JFormattedTextField field = new JFormattedTextField(formatter);
And the trick should be done. with this you can insert up to 5 digits in tour textfield, more '#' in the string parameter for the formatter = more digits can be typed by the user
Try this, This is a complete solution for creating and validating number JTextField
NumberFormat format = NumberFormat.getInstance();
format.setGroupingUsed(false);//Remove comma from number greater than 4 digit
NumberFormatter sleepFormatter = new NumberFormatter(format);
sleepFormatter.setValueClass(Integer.class);
sleepFormatter.setMinimum(0);
sleepFormatter.setMaximum(3600);
sleepFormatter.setAllowsInvalid(false);
sleepFormatter.setCommitsOnValidEdit(true);// committ value on each keystroke instead of focus lost
JFormattedTextField textFieldSleep = new JFormattedTextField(sleepFormatter);
textFieldSleep.setText("0");
Related
I am trying to restrict the input values inside JFormatdedTextField to [0.1, 100] using AbstractFormatter
public AbstractFormatter getFormatter(JFormattedTextField tf) {
NumberFormat f = DecimalFormat.getInstance();
f.setMinimumFractionDigits(1);
f.setMaximumFractionDigits(2);
InternationalFormatter iff= new InternationalFormatter(f);
iff.setAllowsInvalid(false);
iff.setMinimum(0.1);
iff.setMaximum(100.00);
return iff;
}
However, the abstract formatter has a strange behavior. Suppose that I would like to write the following number inside the interval: 0.2.
The abstract formatter blocks the first digit: 0. It is necessary to write 0.2 in 2 phases:
a] 1.2 //or any digit > 0
b] delete 1: 1.2->0.2
Such a behavior is for the user confusing. Is there any way to prevent this uncomfortable writing of numbers?
Thanks for your help.
I think that what you need is a JSPinner:
JSpinner spin = new JSpinner(new SpinnerNumberModel(50 /*or whatever*/, 0.1, 100, 0.1));
or you can just remove the line
iff.setAllowsInvalid(false);
to remove the confusing behavior. The Javadocs for this method say:
Sets whether or not the value being edited is allowed to be invalid
for a length of time (that is, stringToValue throws a ParseException).
It is often convenient to allow the user to temporarily input an
invalid value.
These will let the focus leave the component if the value is invalid and it will be reverted to the previous valid value. If you want to not allow losing focus use an input verifier as in said in the comments. There is an example in the Javadocs of JFormattedTextField: http://docs.oracle.com/javase/8/docs/api/javax/swing/JFormattedTextField.html
I am trying to add a simple currency converter tool to my program yet I hit barrier. Is there a simple way of only allowing float numbers as input to a JTextField in Java. From what I have read online, using JFormattedTextField is a pain to use. Would I need to create a class to do some filtering?
JFormattedTextField shouldnt be all too dificult. Just need to pass in a Formatter in as a parameter and should take care of itself. you can get that from the java API which would use the region settings like so:
new JFormattedTextField(java.text.NumberFormat.getCurrencyInstance());
It would be better to use JFormattedTextField.
Formatted text fields provide a way for developers to specify the valid set of characters that can be typed in a text field. Specifically, the JFormattedTextField class adds a formatter and an object value to the features inherited from the JTextField class. The formatter translates the field's value into the text it displays, and the text into the field's value. See examples.
You can use JFormattedTextField, but it gives a really terrible user experience. Better to discard inappropriate characters as the are entered. DocumentFilter provides a relatively (for Swing) clean way to do this. (Edit: Original answer had links to a trivial example I wrote on my now defunct blog.)
I agree with vcetinick because JFormattedTextField is useful for formatting text input.
However, if you want to verify the value inputted in JTextField, you may need to implement ActionListener yourself:
public void actionPerformed(ActionEvent evt) {
JTextField textfield = (JTextField)evt.getSource();
String strTextValue = textfield.getText();
try {
if (strTextValue.equals("")) {
// Handle empty string
} else {
double dValue = Double.parseDouble(strTextValue);
// Handle valid value
}
} catch (Exception e) {
// Handle invalid value
}
}
I'm a beginner in Java, and NetBeans. I'm trying to make a simple program where you introduce 2 numbers and their sum gets divided by two. However, I'm using JFormattedTExtFields and I don't know how to customize the allowed input in them. Basically I'm trying to find out how to:
Only allow numbers to be entered in JFormmatedTextField;
Only allow a certain amount of numbers;
You could use a NumberFormat and specify the maximum number of integer digits with setMaximumIntegerDigits.
Here's a nice article.
Basically you can do something like:
NumberFormat f = NumberFormat.getNumberInstance();
f.setMaximumIntegerDigits(maxDigitsAmount);
JFormattedTextField field = new JFormattedTextField(f);
The Format should guarantee that the inserted String satisfy the format. Anyway even if a number is supplied, the textfield will store it as a String. So if you need your original Integer you need to rebuild it like suggested #noise:
Integer i = Integer.toString(field.getText());
Hello and thank you in advance for the help.
I am having some trouble formatting using a Java function to mark up a price in HTML.
It seems that, no matter what I do, I cannot insert custom content between the numbers and the decimal (throws Illegal Argument Exception). Is there any known way to achieve the following:
NumberFormat nf = getNumberFormat("'<span class=\"dollars\">'##'</span></span class=\"decimal\">'.'</span></span class=\"cents\">'00'</span>'", locale);
nf.format(number);
Assume locale and number are correctly initialized.
If you look at the docs for DecimalFormat you'll see that they talk about the prefix and the suffix text - but not putting arbitrary text within a number.
It sounds like you should basically write this bit of formatting yourself - possibly using DecimalFormat for each section of the number.
You might consider using String.format(String pattern, Object... arguments). You can pass your simply formatted numbers as arguments.
...
float value = Float.parseFloat((String)model.getValueAt(e.getLastRow(), 1));
DecimalFormat dec = new DecimalFormat("#.###");
model.setValueAt(dec.format(value), e.getLastRow(), 1);
...
at the third line i'm getting the stackOverflowError exception. What I'm intending to do is getting a JTable cell value from an Object, converting it to a float, limiting it to 3 decimal places, and finally convert to String and set the value with 3 decimal places at the cell.
I guess the problem is I'm changing the value, and entering the function again and again. So the StackOverflow is due to that. Question is, how can i fix this?
Complete function at: Java: Converting data types
(Sorry for posting twice... It was a different question, and the solution drove me to a different problem)
The problem is that setValueAt() will, as part of its implementation call tableChanged() on all registered listeners, including this one.
In order to avoid this, simply check whether the value in the cell is already in the desired format as the first thing in your method, and don't do anything if it is.
Just don't call model.setValueAt() if value of the cell is not changed.
It should stop the recursion.
I think this task is usually accomplished by setting a custom editor to the table. So that it formats all input data to a desired form. See this answer.
Perhaps you need something like
String text = (String) model.getValueAt(e.getLastRow(), 1);
String text2 = new DecimalFormat("#.###").format(Float.parseFloat(text));
if (!text.equals(text2))
model.setValueAt(dec.format(value), e.getLastRow(), 1);