1

Hello I want to have a textfield , where the user only can type in numbers and the user isn't able to type in a char. I'm confused because some want to do it with actionlistener some with Formatter and a few more options. Can someone tell me what how to do this? and where to place it in the code that it always checks if there is a letter and deletes it automatically? thx

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;

import java.awt.*;
import java.util.function.UnaryOperator;

public class Controller {

    GuessingGame gg = new GuessingGame();
    //Main m = new Main();


    public Button playButton;
    public Button settingsButton;
    public Button exitButton;

    public TextField textfield;

    public Label countText;
    public Label notification;

    public int currentNumber = 0;
    public int numberBetweenLower = 0;
    public int numberBetweenHigher = 100;

    public void clickedOnExit() {
        System.exit(1);
    }

    ;

    public void clickedOnSettings() {
    }

    ;

    public void clickedOnPlay() {
        Main.pStage.setScene(Main.scene2);
    }

    ;

    public void clickedBackToMenu() {
        Main.pStage.setScene(Main.scene1);
    }

    ;

    public void enteredTextfield() {

        currentNumber = Integer.parseInt(textfield.getText());
        textfield.clear();

        GuessingGame.Result checkNumber;
        checkNumber = gg.evaluateEnteredNumber(currentNumber);
        if (checkNumber == GuessingGame.Result.HIGHER) {
            notification.setText("HIGHER");
        }
        ;
        if (checkNumber == GuessingGame.Result.LOWER) {
            notification.setText("LOWER");
        }
        ;
        if (checkNumber == GuessingGame.Result.EQUALS) {
            notification.setText("YOU GOT IT!");
        }
        ;

        countText.setText("" + gg.getCounter());
    }


    @FXML
    public void initialize() {
        // initialize controller and set text shown in the UI
    }

    private static final class NumberFormatUnaryOperator implements UnaryOperator<TextFormatter.Change> {

        /**
         * Applies this function to the given argument.
         *
         * @param change the function argument
         * @return the function result
         */
        @Override
        public TextFormatter.Change apply(TextFormatter.Change change) {
            var String = change.getControlNewText();

            if (!text.matches("\\d*")) {
                Toolkit.getDefaultToolkit().beep();
                return null;
            }
            return change;
        }
    }
}
Mindmax
  • 49
  • 1
  • 7

1 Answers1

-1

I personally prefer Formatter way, it's pretty simple to use.

For example:

public class TodoListController implements Initializable {

    @FXML
    public TextField input;

    @Override
    public void initialize(final URL url, final ResourceBundle resourceBundle) {
        input.setTextFormatter(new TextFormatter<>(new NumberFormatUnaryOperator()));
    }

    private static final class NumberFormatUnaryOperator implements UnaryOperator<TextFormatter.Change> {

       /**
        * Applies this function to the given argument.
        *
        * @param change the function argument
        * @return the function result
        */
        @Override
        public TextFormatter.Change apply(TextFormatter.Change change) {
           String text = change.getControlNewText();

           if (!text.matches("\\d*")) {
               Toolkit.getDefaultToolkit().beep();
               return null;
           }

           return change;
        }
    }
}

The code above prevents to input any chars at all...

You can also use Listener way, actually both approaches fits very well for what you gonna solve. More over, in terms of JavaFX API, formatters was designed exactly to such kind of use cases. Feel free to use it in your code

Tymur Berezhnoi
  • 706
  • 1
  • 14
  • 27
  • thanks for your response, so I should initialize the variable text to my input of the textfield? My code is above (edidted) – Mindmax Jan 31 '20 at 11:46
  • 1
    assuming you mean a listener to the textProperty (and resetting its value if it doesn't fit) - that's not an option, in fact it would be plain wrong :) – kleopatra Jan 31 '20 at 13:24
  • @Mindmax I updated my code slightly... All I meant is that you can assign a text formatter to a text field, and in my example it will allow you to prevent non digit input during typing, so it means no char will appear in the text field at all, but only digits. So, just try to play around the example and find what is best for your case. – Tymur Berezhnoi Jan 31 '20 at 13:47
  • @t-jd THX so much I got it right now. I was a little bit to dump for this haha – Mindmax Feb 04 '20 at 13:06