2

I want to set up a model for my project so my controllers can communicate with each other. I want it to have a setter and getter, to allow easy access to styling certain nodes from either class.

My question: is it possible to bind a style property (ex. "-fx-background-color: blue") to a node?

From my research, I see that this is definitely possible with text values for labels (explained by James_D here: JavaFX - How to use a method in a controller from another controller?), but I am having a hard time figuring out what the syntax for doing a similar thing with "setStyle" would be.

The model I have so far:

 public class Model {

    private final StringProperty shadow = new SimpleStringProperty("-fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.24), 10,0,0,0)");

    public StringProperty shadowProperty() {
        return shadow;
    }

    public final String getShadow() {
        return shadowProperty().get();
    }

    public final void setShadow(String shadow) {
        shadowProperty().set(shadow);
    }
}

I understand how I would set the "shadow" value from a controller, but what I don't understand is how I can bind a node from another controller to listen to that change.

Let's say the node is something like:

@FXML AnchorPane appBar

I want "appBar" to take on any changes made to "shadow" in the model. What would that look like?

Community
  • 1
  • 1
Shane
  • 115
  • 1
  • 3
  • 17
  • 2
    Can you give an example of what you tried, and explain why it didn't work? It is unclear at the moment what the exact problem is. – Itai Mar 22 '16 at 06:11

1 Answers1

5

You need to add a listener to the shadowProperty to listen to its changes.

something.shadowProperty() .addListener( (observable, oldValue, newValue) -> {
    //do something with appBar 
}) ;

I'm not entirely sure what you want to achieve, but this should answer your question about how to listen to property changes.

PS: im on mobile, so no guarantees regarding typos

Edit: you can also bind the property of one object to the property of another. Use bind() for that.

EDIT: Here is an example:

import javafx.application.Application;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.Scene;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

    Property<Background> backgroundProperty;
    StringProperty styleProperty;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        VBox root = new VBox(10);

        backgroundProperty = new SimpleObjectProperty<>();
        styleProperty = new SimpleStringProperty();

        // Pane that changes background by listener
        Pane pane1 = new Pane();
        pane1.setMinHeight(40);
        backgroundProperty.addListener( (observable, oldValue, newValue) -> {
            pane1.setBackground(backgroundProperty.getValue());
        });

        // Pane that changes background by property binding
        Pane pane2 = new Pane();
        pane2.setMinHeight(40);
        pane2.backgroundProperty().bind(backgroundProperty);

        // Pane that binds the style property
        Pane pane3 = new Pane();
        pane3.setMinHeight(40);
        pane3.styleProperty().bind(styleProperty);

        backgroundProperty.setValue(new Background(new BackgroundFill(Color.RED, null, null)));
        styleProperty.setValue("-fx-background-color: black");

        root.getChildren().add(pane1);
        root.getChildren().add(pane2);
        root.getChildren().add(pane3);

        Scene scene = new Scene(root, 200, 400);
        primaryStage.setScene(scene);
        primaryStage.show();

    }
}
JohnRW
  • 748
  • 7
  • 22