Search code examples
classjavafxcolorsjavafx-2pane

How to change a pane color from a different class in javaFX


I have some input validation that I'm doing from the action of the user typing into a textbox. I want it to become orange when letters are input and white when numbers are put in. The problem I'm having is I can't think of a way to change the color once the application realizes that it is a number or letter.

I need it to get the input of the user, look at the TypedKey class then look at the if, else if and based on that change the color in the scene. This is the most logical way I can think of doing it, but if anyone knows a more efficient way, or can help me improve upon the way I'm thinking it would be much appreciated.

@Override
public void start(Stage primaryStage) throws Exception {
    GridPane pane = new GridPane();
    pane.setHgap(5);
    pane.setVgap(5);
    pane.setAlignment(Pos.CENTER);

    Scene scene = new Scene(pane, 300, 200);
    pane.add(new Label("Salary and Wage"), 0, 0);
    pane.add(tfSalaryAndWage, 1, 0);
    pane.add(btOK, 1, 1);

    //Red color for tfSalary box
    Color redColor = Color.rgb( 255, 0 , 0, 0.5);
    BackgroundFill backgroundFill = new BackgroundFill(redColor, null, null);
    Background background= new Background(backgroundFill);
    tfSalaryAndWage.setBackground(background);


    TypedKey typedKeyHandler = new TypedKey(this);
    tfSalaryAndWage.setOnKeyTyped(typedKeyHandler);

    primaryStage.setScene(scene);
    primaryStage.setTitle("Loan Calculator");
    primaryStage.show();
}

Input validation class

class TypedKey implements EventHandler<KeyEvent> {
    ValidateDataTest formObj = null; // Declare a data member to represent an
                                        // object of the form class.

    Color blueBackgroundColor = null;

    public TypedKey(ValidateDataTest formObj) // This constructor receives an
                                                    // object of the form class.
    {
        this.formObj = formObj;
    }

    public void handle(KeyEvent e) {
        if ((e.getCharacter().compareTo("a") >= 0 && e.getCharacter()
                .compareTo("z") <= 0)
                || (e.getCharacter().compareTo("A") >= 0 && e.getCharacter()
                        .compareTo("Z") <= 0)) {
            System.out.println("LOOKS LIKE A Z WAS PRESSED");



        }

        else if ((e.getCharacter().compareTo("0") >= 0 && e.getCharacter()
                .compareTo("9") <= 0)) {
            System.out.println("LOOKS LIKE NUMBERS WERE PRESSED");

        }

    }
}

Solution

  • You do not need a separate class for your requirement. A simple change listener on the textProperty() of the textfield should be good enough.

    textField.textProperty().addListener((ob, oldValue, newValue) -> {
         if (isNumeric(newValue)) {
             scene.setFill(Color.AQUA);
         } else {
             scene.setFill(Color.FIREBRICK);
         }
    });
    

    where, isNumeric() is just a private method that I wrote.

    private boolean isNumeric(String str) {
        for(Character ch : str.toCharArray()){
            if(Character.isAlphabetic(ch)){
                return false;
            }
        }
        return true;
    }
    

    MVCE

    import javafx.application.Application;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.VBox;
    import javafx.scene.paint.Color;
    import javafx.stage.Stage;
    
    public class TextFieldBindSceneColor extends Application {
        @Override
        public void start(Stage primaryStage) throws Exception {
    
            TextField textField = new TextField();
            VBox box = new VBox(textField);
            box.setAlignment(Pos.CENTER);
            box.setStyle("-fx-background-color: transparent");
            Scene scene = new Scene(box, 200, 200);
    
            textField.textProperty().addListener((ob, oldValue, newValue) -> {
                if (isNumeric(newValue)) {
                    scene.setFill(Color.AQUA);
                } else {
                    scene.setFill(Color.FIREBRICK);
                }
            });
            //scene.setFill(Color.RED);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        private boolean isNumeric(String str) {
            for(Character ch : str.toCharArray()){
                if(Character.isAlphabetic(ch)){
                    return false;
                }
            }
            return true;
        }
    }