首页 > 解决方案 > JavaFX 无法设置自定义属性

问题描述

我正在尝试将自定义属性实现到我的 JavaFX 应用程序的自定义组件中。我已经阅读了一些教程,并且都将我指向了下面的方向。

由于某种原因,它不起作用。当我尝试在 FXML 文件中设置属性值并且场景构建器也不显示该属性时,IntelliJ 不喜欢。

标签控制器:

public class LabelController {

    @FXML
    public Label label;

    // Define a variable to store the property
    private DoubleProperty amountDue = new SimpleDoubleProperty();

    // Define a getter for the property's value
    public final double getAmountDue(){return amountDue.get();}

    // Define a setter for the property's value
    public final void setAmountDue(double value){amountDue.set(value);}

    // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {return amountDue;}

    public void onMouseEntered(MouseEvent mouseEvent) {
        FadeToHoverColour();
    }

    public void onMouseExited(MouseEvent mouseEvent) {
        FadeToDefaultColour();
    }

    public void FadeToHoverColour() {
        Timeline timeline = new Timeline();
        timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0.2), new KeyValue(label.textFillProperty(), Paint.valueOf("E63700"))));
        timeline.play();
    }

    public void FadeToDefaultColour() {
        Timeline timeline = new Timeline();
        timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(0.2), new KeyValue(label.textFillProperty(), Paint.valueOf("FF774D"))));
        timeline.play();
    }
}

标签.fxml:

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx"
      xmlns:fx="http://javafx.com/fxml"
      fx:controller="madoc.controllers.components.LabelController">
    <Label fx:id="label"
           text="TEXT"
           onMouseEntered="#onMouseEntered"
           onMouseExited="#onMouseExited">
    </Label>
</VBox>

WelcomeSceneBuilder.fxml:

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

<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="madoc.controllers.scenes.WelcomeSceneController">
    <fx:include source="./Label.fxml" [NOT WORKING WHEN I TRY TO SET AMOUNT DUE HERE]/>
</AnchorPane>

标签: javajavafxscenebuilder

解决方案


添加到元素的属性/子<fx:include>元素适用于加载其他 fxml 的结果,即在这种情况下,创建的对象类型是VBox,而不是LabelControllerVBox不包含您尝试分配的属性。

您不能仅使用 fxml 来执行此操作。您需要使用initialize控制器的方法来设置属性值:

欢迎场景控制器

@FXML
private LabelController labelController;

@FXML
private void initialize() {
    labelController.setAmountDue(...);
}

WelcomeSceneBuilder.fxml

...
<fx:include source="./Label.fxml" fx:id="label"/>
...

您可以使用自定义组件方法,尽管这会使控制器和节点成为同一个对象,从而允许您进行此类分配。由于缺乏关于节点职责的信息,我保留了LabelController,但您当然应该选择一个更好的名称。

package madoc.controllers.components;

...

public class LabelController extends VBox {

    public LabelController() {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/madoc/controllers/components/Label.fxml")); // TODO: replace with correct resoure path?
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.load();
        } catch(IOException ex) {
            throw new IllegalStateException("Could not load fxml file", ex);
        }
    }

    @FXML
    public Label label;

    // Define a variable to store the property
    private final DoubleProperty amountDue = new SimpleDoubleProperty();

    // Define a getter for the property's value
    public final double getAmountDue(){return amountDue.get();}

    // Define a setter for the property's value
    public final void setAmountDue(double value){amountDue.set(value);}

    // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {return amountDue;}

    ...
}

标签.fxml

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

<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<fx:root xmlns="http://javafx.com/javafx"
      xmlns:fx="http://javafx.com/fxml"
      type="javafx.scene.layout.VBox">
    <Label fx:id="label"
           text="TEXT"
           onMouseEntered="#onMouseEntered"
           onMouseExited="#onMouseExited">
    </Label>
</fx:root>

WelcomeSceneBuilder.fxml

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

<?import javafx.scene.layout.AnchorPane?>
<?import madoc.controllers.components.LabelController?>

<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="madoc.controllers.scenes.WelcomeSceneController">
    <LabelController amountDue="30.05"/>
</AnchorPane>

推荐阅读