Search code examples
javaobjectjavafxnodes

How can I get a Button's text in JavaFX if the Button is being read as a Node? Looping through Group/VBox of Buttons. Returns it as Nodes


I'm learning JavaFX and this is just a small programming question.

I have 3 buttons in a VBox. And I want to apply the same 3 effects on all buttons after I put them in the Vbox. But when I use a for loop and getChildren() on the VBox, they are returned as 'Nodes'. I can't use the Button.getText() to find out the text of the button.

Is there a way I can getText of a Node? Or maybe convert the current Node to a Button and get the text that way?

VBox vbox = new VBox();

Button option1 = new Button("Single Player");
Button option2 = new Button("Network Player");
Button option3 = new Button("View Rules");

vbox.getChildren().add(option1);
vbox.getChildren().add(option2);
vbox.getChildren().add(option3);

for (final Node button : vbox.getChildren()) {
    button.setOnMouseEntered(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent arg0) {
            button.setEffect(addEffect(Color.web("#53CFA6"), .8, 10));
        }
    });
    button.setOnMouseExited(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent arg0) {
            button.setEffect(addEffect(Color.web("#FF6800"), .8, 10));
        }
    });

    button.setOnMouseClicked(new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent arg0) {
            button.setEffect(addEffect(Color.web("#E62800"), .8, 10));

            //Need to use button.getText()
            //Button button; button.getText() works

        }
    });
}

Solution

  • there is two options:

    1. Convert types. Easy, but not safe.

    If you sure you wouldn't add other children to this VBox you can just convert Node to Button:

    for (Node node : vbox.getChildren()) {
        if (node instanceof Button) {
            final Button button = (Button) node;
    
            // all your logic
        }
    

    2. Use Factory pattern. Best suites, IMHO.

    introduce method createButton which will setup button as you need:

    private Button createButton(String name) {
        final Button button = new Button(name);
        button.setOnMouseEntered(...);
        button.setOnMouseExited(...);
        button.setOnMouseClicked(...);
        return button;
    }
    

    and you code will look next way:

    Button option1 = createButton("Single Player");
    Button option2 = createButton("Network Player");
    Button option3 = createButton("View Rules");
    
    vbox.getChildren().addAll(option1, option2, option3);
    

    3. Introduce your own Button class. Better if you plan to extend buttons logic.

    public void FancyButton extends Button {
        public FancyButton(String name) {
            super(name);
            //handlers logic here
        }
    }