Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recommended way to restrict input in JavaFX textfield

It may seem the question is the duplicate of this. But my question is i have developed a integer textfield in JavaFX by two ways. The code is given below

public class FXNDigitsField extends TextField
{
private long m_digit;
public FXNDigitsField()
{
    super();
}
public FXNDigitsField(long number)
{
    super();
    this.m_digit = number;
    onInitialization();
}

private void onInitialization()
{
    setText(Long.toString(this.m_digit));
}

@Override
public void replaceText(int startIndex, int endIndex, String text)
{
    if (text.matches(Constants.DIGITS_PATTERN) || text.equals(Constants.EMPTY_STRING)) {
        super.replaceText(startIndex, endIndex, text);
    }
}

@Override
public void replaceSelection(String text)
{
    if (text.matches(Constants.DIGITS_PATTERN) || text.equals(Constants.EMPTY_STRING)) {
        super.replaceSelection(text);
    }
}
}

And the second way is by adding an event Filter.

The code snippet is given.

 // restrict key input to numerals.
this.addEventFilter(KeyEvent.KEY_TYPED, new EventHandler<KeyEvent>() {
  @Override public void handle(KeyEvent keyEvent) {
    if (!"0123456789".contains(keyEvent.getCharacter())) {
      keyEvent.consume();
    }
  }
});

My question is which is the slandered way to do this? Can anyone help me to pick up the right?

like image 686
Nikhil Avatar asked Mar 25 '13 13:03

Nikhil


People also ask

How do I make text field not editable in JavaFX?

In order to create a non editable JTextField , all you have to do is: Create a class that extends JFrame . Create a new JTextField . Use setEditable(false) that sets the specified boolean to indicate whether or not this textfield should be editable.

How do you add a text field in JavaFX?

Creating a Text FieldLabel label1 = new Label("Name:"); TextField textField = new TextField (); HBox hb = new HBox(); hb. getChildren(). addAll(label1, textField); hb. setSpacing(10);

What is TextField in JavaFX?

TextField class is a part of JavaFX package. It is a component that allows the user to enter a line of unformatted text, it does not allow multi-line input it only allows the user to enter a single line of text. The text can then be used as per requirement.

Can you change the display character of TextField?

You can't, however, change their basic appearance. . From TextComponent they inherit methods that allow them to set and get the current selection, enable and disable editing, get the currently selected text (or all the text), and set the text.


3 Answers

The best way to add validation in TextField is a 3rd way. This method lets TextField finish all processing (copy/paste/undo safe). It does not require you to extend the TextField class. And it allows you to decide what to do with new text after every change (to push it to logic, or turn back to previous value, or even to modify it).

// fired by every text property changes
textField.textProperty().addListener(
  (observable, oldValue, newValue) -> {
    // Your validation rules, anything you like
    // (! note 1 !) make sure that empty string (newValue.equals("")) 
    //   or initial text is always valid
    //   to prevent inifinity cycle
    // do whatever you want with newValue

    // If newValue is not valid for your rules
    ((StringProperty)observable).setValue(oldValue);
    // (! note 2 !) do not bind textProperty (textProperty().bind(someProperty))
    //   to anything in your code.  TextProperty implementation
    //   of StringProperty in TextFieldControl
    //   will throw RuntimeException in this case on setValue(string) call.
    //   Or catch and handle this exception.

    // If you want to change something in text
    // When it is valid for you with some changes that can be automated.
    // For example change it to upper case
    ((StringProperty)observable).setValue(newValue.toUpperCase());
  }
);
like image 154
gmatagmis Avatar answered Nov 26 '22 05:11

gmatagmis


JavaFX has a class TextFormatter for this use-case. It allows you to validate and adjust the text content before it is "commited" to the textProperty of the TextField.

See this example:

TextFormatter<String> textFormatter = new TextFormatter<>(change -> {
    if (!change.isContentChange()) {
        return change;
    }

    String text = change.getControlNewText();

    if (isValid(text)) { // your validation logic
        return null;
    }


    return change;
});

textField.setTextFormatter(textFormatter);
like image 39
Manuel Mauky Avatar answered Nov 26 '22 07:11

Manuel Mauky


In both of your ways, you are not allowed to type characters other then numeric characters. But it will allow to paste any character there (Copy Text from any source and Paste in your TextField).

A good way to do validation is after submitting it,

Like (For integers):

try {
    Integer.parseInt(myNumField.getText());
} catch(Exception e) {
    System.out.println("Non-numeric character exist");
}

(or you can use any combination of yours + the above method)

like image 35
Shreyas Dave Avatar answered Nov 26 '22 06:11

Shreyas Dave