AlvinL
AlvinL

Reputation: 448

How to update node state in JavaFX?

public Card(Suit suit, Rank rankString, boolean hide) {
        this.suit = suit;
        this.rankString = rankString;
        this.hide = hide;

        if (!this.hide) {
            HashMap<String, String> map = cardNames();
            String thisCard = suit.toString()+rankString.toString();

            Image cardDP = new Image("file:E:/Javaworkspace/Project/resource/"+ map.get(thisCard) +".png");
            ImageView iv = new ImageView();
            iv.setImage(cardDP);
            getChildren().add(new StackPane(iv));

        } else {
            Image img = new Image("file:E:/Javaworkspace/Project/resource/blank.png");
            ImageView iv = new ImageView();
            iv.setImage(img);
            getChildren().add(new StackPane(iv));
        }

    }

There is a deck of cards generated with hide = false. The problem is: GUI does not reflect the change of hide status when I use the setHide() for a particular Card instance.

Which leads me to believe either the constructor isn't doing what it is supposed to do OR the GUI needs something else to understand that it needs to display the alternative picture when a card is faced down. In either case, what do I have to do to have changes reflected in the GUI?

Upvotes: 1

Views: 3549

Answers (1)

Sergey Grinev
Sergey Grinev

Reputation: 34498

You need to update state each time as constructor is called only once. The cool way to do it in JavaFX is to use proprety binding! See next example

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class FXCards extends Application {

    private class Card extends StackPane {

        // we declare a property here
        final BooleanProperty hideProperty = new SimpleBooleanProperty();

        public Card(boolean hide) {
            hideProperty.setValue(hide);

            Image cardDP = new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/a/a5/52_K_di_picche.jpg/174px-52_K_di_picche.jpg");
            ImageView iv = new ImageView(cardDP);
            getChildren().add(iv);

            Image cardBack = new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/8/86/Carta_Francese_retro_Blu.jpg/174px-Carta_Francese_retro_Blu.jpg");
            ImageView ivBack = new ImageView(cardBack);
            getChildren().add(ivBack);

            // binding to hideProperty
            // card back is visible if hide property is true
            ivBack.visibleProperty().bind(hideProperty);
            // card front is visible if property is false, see "not()" call
            iv.visibleProperty().bind(hideProperty.not());

            setOnMouseClicked((e)-> {
                // click on card to flip it
                hideProperty.setValue(!hideProperty.getValue());
            });
        }

    }


    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();

        root.getChildren().add(new Card(true));

        Scene scene = new Scene(root, 300, 500);
        primaryStage.setTitle("Click to Flip!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

Upvotes: 2

Related Questions