JavaFX SceneBuilder 绑定对象属性

JavaFX SceneBuilder Binding ObjectProperty

我不熟悉在 JavaFX SceneBuilder 中使用 ObjectProperties,因此我正在寻求帮助。

我想将一种颜色绑定到一个窗格,这样该窗格就会被这种颜色填充。 这是我试过的

// Pane background colors
ObjectProperty<Paint> paneColor = new SimpleObjectProperty<>(Color.TRANSPARENT);
ObjectProperty<Background> paneBackground = new SimpleObjectProperty<>(new Background(new 

BackgroundFill(paneColor.get(), CornerRadii.EMPTY, Insets.EMPTY)));
ObjectProperty<Paint> paneBorderColor = new SimpleObjectProperty<>(Paint.valueOf("#c9d4cc"));

controller.getBackgroundPane().backgroundProperty().bind(paneBackground);
controller.getBackgroundPane().setStyle("-fx-border-color: " + paneBorderColor.get());

public Paint getPaneColor() {
        return paneColor.get();
    }
    
    public void setPaneColor(Paint color) {
        this.paneColor.set(color);
    }
    
    public Paint getPaneBorderColor() {
        return this.paneBorderColor.get();
    }
    
    public void setPaneBorderColor(Paint color) {
        this.paneBorderColor.set(color);
    }
    
    public Background getPaneBackgroundColor() {
        return this.paneBackground.get();
    }
    
    public void setPaneBackgroundColor(Background background) {
        this.paneBackground.set(background);
    }

颜色不会显示在窗格上,但它们的 属性 字段会显示在 SceneBuilder 编辑器中。但是,当我通过 SceneBuilder 编辑它们时,它们并没有改变。

有人可以澄清一下我做错了什么吗?谢谢:)

编辑:

现在一切正常,但我想将一种颜色绑定到窗格的边框颜色。我使用绑定到窗格的样式 属性 的 StringProperty 尝试了这种方法。它有效,但我很好奇是否有更有效的方法(我可以在 SceneBuilder 中使用颜色选择器而不必使用 CSS 对边框宽度进行编码)。

这是我的代码:

StringProperty paneBorderColor = new SimpleStringProperty("#c9d4cc");

controller.getBackgroundPane().styleProperty().bind(Bindings.createStringBinding(() -> 
"-fx-border-color: " + paneBorderColor.get() + "; -fx-border-width: 2px 0px 2px 0px", 
paneBorderColor));

public String getPaneBorderColor() {
    return this.paneBorderColor.get();
}
    
public void setPaneBorderColor(String color) {
    this.paneBorderColor.set(color);
}

如果在 Scene Builder 中更改颜色 属性 时没有发生任何效果,则绑定不正确。您可以使用 Bindings.createObjectBinding(...)。这是它如何工作的示例:

编辑: 添加了边框颜色和宽度的示例。

控制器:

package custom.control;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.layout.*;
import javafx.scene.paint.Paint;

public class Controller implements Initializable {

    @FXML
    private Pane pane;

    private final ObjectProperty<Paint>
            backgroundColor = new SimpleObjectProperty<>(),
            borderColor = new SimpleObjectProperty<>();

    private final DoubleProperty
            borderWidth = new SimpleDoubleProperty();


    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        // Binding for background color:
        pane.backgroundProperty().bind(Bindings.createObjectBinding(() ->
                        new Background(new BackgroundFill(backgroundColor.get(),
                                CornerRadii.EMPTY, Insets.EMPTY)),
                backgroundColor));

        // Binding for border color and width:
        pane.borderProperty().bind(Bindings.createObjectBinding(() ->
                        new Border(new BorderStroke(borderColor.get(),
                                BorderStrokeStyle.SOLID,
                                CornerRadii.EMPTY,
                                new BorderWidths(borderWidth.get()))),
                borderColor, borderWidth));
    }

    public ObjectProperty<Paint> backgroundColorProperty() {
        return backgroundColor;
    }

    public ObjectProperty<Paint> borderColorProperty() {
        return borderColor;
    }

    public DoubleProperty borderWidthProperty() {
        return borderWidth;
    }
}

自定义窗格:

package custom.control;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.fxml.FXMLLoader;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;

import java.io.IOException;

public class CustomPane extends AnchorPane {

    private final ObjectProperty<Paint>
            backgroundColor = new SimpleObjectProperty<>(Color.BLACK),
            borderColor = new SimpleObjectProperty<>(Color.RED);

    private final DoubleProperty
            borderWidth = new SimpleDoubleProperty(3);

    public CustomPane() {
        super();

        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("custom-pane.fxml"));

            Controller controller = new Controller();
            loader.setController(controller);

            Pane root = loader.load();
            this.getChildren().add(root);

            AnchorPane.setTopAnchor(root, 0d);
            AnchorPane.setRightAnchor(root, 0d);
            AnchorPane.setBottomAnchor(root, 0d);
            AnchorPane.setLeftAnchor(root, 0d);

            controller.backgroundColorProperty().bind(backgroundColor);

            controller.borderWidthProperty().bind(borderWidth);
            controller.borderColorProperty().bind(borderColor);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public Paint getBackgroundColor() {
        return backgroundColor.get();
    }

    public ObjectProperty<Paint> backgroundColorProperty() {
        return backgroundColor;
    }

    public void setBackgroundColor(Paint backgroundColor) {
        this.backgroundColor.set(backgroundColor);
    }

    public Paint getBorderColor() {
        return borderColor.get();
    }

    public ObjectProperty<Paint> borderColorProperty() {
        return borderColor;
    }

    public void setBorderColor(Paint borderColor) {
        this.borderColor.set(borderColor);
    }

    public double getBorderWidth() {
        return borderWidth.get();
    }

    public DoubleProperty borderWidthProperty() {
        return borderWidth;
    }

    public void setBorderWidth(double borderWidth) {
        this.borderWidth.set(borderWidth);
    }
}

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.Pane?>


<Pane fx:id="pane" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" />

场景生成器预览: