How to restrict textfield input only number and decimal? [duplicate] - java

This question already has answers here:
Restricting JTextField input to Integers [duplicate]
(6 answers)
Closed 3 years ago.
I want to control user input text on jtextfield. It seems I can't find any good way in netbean 8. in C# use keypress event, but in java I'm new.
I choose key type event
I want input only number with 2 digit after decimal
10.00
1224547885544.12
545545464646464646465466.10
not
12121212.654654654654
I've tried
// not a good idea
char c=evt.getKeyChar();
if((Character.isDigit(c))||(c==KeyEvent.VK_PERIOD)||(c==KeyEvent.VK_BACK_SPACE)){
int punto=0;
if(c==KeyEvent.VK_PERIOD){
String s=pricefield.getText();
int dot=s.indexOf('.');
punto=dot;
if(dot!=-1){
getToolkit().beep();
evt.consume();
}
}
}
else{
getToolkit().beep();
evt.consume();
}
//second try
char enter = evt.getKeyChar();
if(!(Character.isDigit(enter))){
evt.consume();
}
it's not good idea I think.
try other many ways.
please, help me.

Assuming you are referring to a JavaFX TextField:
You can get the textProperty of the textfield by calling textField.textProperty(). Since this is a property, you can attach a listener to it, to listen for changes to the text in the field:
textField.textProperty().addListener((observable, oldValue, newValue) -> {
// this code is called whenever the text in the field changes
// oldValue is the text contained before the event was triggered
// newValue is the text that the field is about to be set to
if (oldValue.contains("[a-zA-Z]")) { // any predicate you want/need
textField.setText(oldValue); // revert the text of the field back to its old value
}
});

For a Swing TextField, that should help you:
JFormattedTextField textField = new JFormattedTextField();
textField.setFormatterFactory(new AbstractFormatterFactory() {
#Override
public AbstractFormatter getFormatter(JFormattedTextField tf) {
NumberFormat format = DecimalFormat.getInstance();
//or two, if you want to force something like 10.00
format.setMinimumFractionDigits(0);
format.setMaximumFractionDigits(2);
format.setRoundingMode(RoundingMode.HALF_UP);
InternationalFormatter formatter = new InternationalFormatter(format);
formatter.setAllowsInvalid(false); //important!
return formatter;
}
});

Related

UPDATE of How to get string from JTextField and save it in variable?

I recently run in to same problem as this guy 4 years before. He get some answers there but non of it work either for him or me and then the question was not updated anymore.
How to get string from JTextField and save it in variable?
The point is to check what is typed in textfield and if, like in example is yet decimal dot in the TextField, then consume event and not allow to add second decimal dot.
Main problem I figured out is that I need to add this inside the key event as shown belox. But this. statement inside the event reffers to event itself and not on JTextField.So I need to find bypass or other solution how to write getText statement
String text = this.getText().toString();
if someone have ideas of how to improve code as well I'm opened to any suggestions except for rewriting it as formatted field because the user experience is a little different, from the point where I was trying formatted field.
public class TxtfNumber extends JTextField {
String text = this.getText().toString();
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
String text = this.getText().toString();
if(evt.getKeyChar()=='.'&& text.contains(".")){
evt.consume();
}
}
return false;
}
});
}
}
SOLUTION
I accidentally run in solution when I used lambda expression. The formula you need to use is the name of class then .this.
So in this case,
String text = TxtfNumber.this.getText().toString();
is the solution.
But eventually, when I know how to implement JTextField, I no longer need a solution by string. So I'm giving the whole code here for later use. Feel free to use it as Choose Bean component.
It restricts the user to use only one minus sign at the start of the text, one decimal dot anywhere and then type in two decimal numbers.
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.event.KeyEvent;
import javax.swing.JTextField;
public class TxtfNumber extends JTextField {
public TxtfNumber(){
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new KeyEventDispatcher() {
#Override
public boolean dispatchKeyEvent(KeyEvent evt) {
switch (evt.getID()) {
case KeyEvent.KEY_TYPED:
//restricts input charactes
if(!Character.isDigit(evt.getKeyChar()) && (evt.getKeyChar()!='.') && (evt.getKeyChar()!='-') && (evt.getKeyChar()!=','))
evt.consume();
//change , and . for securing of different keyboard language
if (evt.getKeyChar()==',')
evt.setKeyChar('.');
//allow only one decimal dot in text
if (evt.getKeyChar()=='.' && TxtfNumber.this.getText().contains("."))
evt.consume();
//allow minus sign only at the start of text
if (evt.getKeyChar()=='-' && TxtfNumber.this.getText().length() != 0)
evt.consume();
//allow two decimal numbers after dot
for (int i = -1; (i = TxtfNumber.this.getText().indexOf(".", i + 1)) != -1; i++) {
if (i+3 == TxtfNumber.this.getText().length())
evt.consume();
}
break;
}
return false;
}
});
}
};

Value from button to be set in the next available JTextField?

In my app, I need for values from buttons (the value is taken from an SQLite database) to be displayed in one of 13 JTextFields, and they can be in any order. How do I make it possible for the value to be displayed in the next available JTextField, if say the first one is empty?
The only thing I could think of was
if (textField.getText().isEmpty())
{
String text = String.valueOf(num);
textField.setText(textField.getText() + text);
}
What should I do next? How should I go around the else statement? Should I even use it?
Thanks in advance!
If I understand your question correctly,this should be the idea
JTextField[] fields = new JTextField[13];
firstText.setName("First Text") ;
.......
field[0] = firstText;
field[1] = SecondText;
//then add remaining textfields
for(JTextField txtField : fields) {
if(txtField.getText().equals("") ) {
// do whatever you want
}else{
// do whatever you want
}
}

jformattedtextfield rounded numbers

i have a JFormattedTextField , and i want that when i try to enter a number, example 1002 , that i will rounded to the nearest multiple of 5
1002->1000
304->305
6->5
9->10
1->0
etc..
i've already setup a number format to cancel the grouping, and accepting only numbers
NumberFormat format=NumberFormat.getInstance();
format.setGroupingUsed(false);
pun1[i]=new JFormattedTextField(format); //pun1 and pun2 are the arrays of FIELDS
pun2[i]=new JFormattedTextField(format);
how can i resolve this problem?
I want this editing inside the field, while i'm writing the number, just as when the grouping character appears!
This works for int arguments:
public int roundToClosestFive(int num) {
return (int) (Math.round(num / 5.0) * 5);
}
Remember, to get the int value of the string you've entered you can do: Integer.valueOf(string); and pass that as an argument to the method. To have the text inside the JFormattedTextField change on focus change or enter, you could call the above method from the propertyChange() method of a PropertyChange listener that you can add to the JTextFormattedTextField. Something like this in the propertyChange() method:
public void propertyChange(PropertyChangeEvent e) {
Object source = e.getSource();
if (source == pun1[i]) {
((JFormattedTextField) source).setText(""
+ roundToClosestFive(((Number)pun1[i].getValue()).intValue()));
}
}

Get boolean from a JTextField

I am trying to take the values from the text fields below to use with parent.addNewRoom(roomNo,roomEnSuite); but roomEnSuite is a Boolean value in the parent class. What is the correct procedure to get a Boolean from a JTextField?
public void actionPerformed( ActionEvent ae)
{
String item = ae.getActionCommand();
if ( item.equals("Confirm"))
{
String roomNo = nameJTextField.getText();
String roomEnSuiteS = idJTextField.getText();
parent.addNewRoom(roomNo,roomEnSuite);
this.dispose();
}
else if ( item.equals("Cancel"))
{
parent.resetButtons();
this.dispose();
}
}
To give a full answer from my above comments:
Handling boolean input using a JTextField would not be a good way to go about things as there are many variations the user could type yes/no/true/false, etc. mispelling?
Using a JRadioButton (for single answers) or JCheckbox (for multiple answers) would be a better way to go about handling true or false input. I would suggest a JRadioButton as you wouldn't want the user checking true and false.
http://docs.oracle.com/javase/tutorial/uiswing/components/button.html
Assuming the user entered the string true or false, you can turn it into a boolean with:
boolean value = Boolean.parseBoolean(idJTextField.getText());
A JTextField is meant to provide Strings. So unless you want the user to type true or false in the textfield (or whatever string you will parse to a boolean), there are better options available
a JCheckBox, which is typically used for toggle settings, like true-false
JRadioButtons (one for each setting, so two in this case)
And here a link to the corresponding Swing tutorial with examples on how to use these buttons
But if you really want to got with a textfield, then you should get the text from it and parse it by using for example Boolean.valueOf
As long as the value entered is always going to be true or false you can get a Boolean using;
boolean value = Boolean.parseBoolean(enSuiteJTextField.getText());

KeyPressed event

I'm trying to learn something about GUI, using NetBeans6.8, starting with the GUI section in The java tutorial.
There is a simple exercise for a Celsius-Fahrenheit converter. I want that to have two TextFields, one for Celsius and one for Fahrenheit temperature; if the user types in the celsius text field he got the result "printed" in the fahrenheit text filed. and vice versa.
So, i put on both the textfields one KeyTyped event, here's the code:
private void celsiusTextKeyTyped(java.awt.event.KeyEvent evt) {
int cels = Integer.parseInt(celsiusText.getText());
int fahr = (int)(cels * 1.8 + 32);
fahrText.setText(fahr + "");
}
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt) {
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
It doesn't work. If i type something in a textfield i got this exception: java.lang.NumberFormatException: For input string: ""
The code that attach the listeners:
celsiusText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
celsiusTextKeyTyped(evt);
}
});
fahrText.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
fahrTextKeyTyped(evt);
}
});
[However, i can't modify it, it's autogenerated.]
Method .getText() returns a string not a number, if that string contains non-numeric characters (i.e. a letter, a space, nothing at all) then parseInt will throw a NumberFormatException. Since your using KeyEvent, as soon as you press say "7", the event is fired before 7 is entered into the text box. Thus the text box still only contains "", which is where the error comes from. You may wish to also listen to the keyUp event instead.
You need to enclose your code in a try catch block.
private void fahrTextKeyTyped(java.awt.event.KeyEvent evt)
{
try
{
int fahr = Integer.parseInt(fahrText.getText());
int cels = (int)(fahr / 1.8 - 32);
celsiusText.setText(cels + "");
}
catch(NumberFormatException ex)
{
//Error handling code here, i.e. informative message to the user
}
}
An alternative is you could filter out non-numbers on keydown event, see example here - http://www.javacoffeebreak.com/java107/java107.html (Creating a custom component - NumberTextField)
I suspect that what's happened is that you added these handlers with something like celsiusText.addKeyListener, yes?
The thing is, that'll give you not just the KEY_TYPED events you wanted, but also KEY_DOWN and KEY_UP. The KEY_DOWN event will happen before the text is really entered into the field, so your code firing on that will see the field as blank still. Trying to convert the empty string to a number gives you a format exception.
The easiest way to fix this is the try/catch construct other people have been posting.
You probably set action to keyDown, this mean that even occur before the key value is "added" to textbox, while You retrieve the value from it is still empty "".
There is a simple exercise for a
Celsius-Fahrenheit converter
That is a really old example. The better approach is to use a DocumentListener, not a KeyListener.

Categories