简体   繁体   中英

JavaFX Unable To Set Custom Properties

I'm trying to implement custom properties into a custom component for my JavaFX application. I've read some tutorials and all have pointed me in the direction of below.

For some reason, it's not working. IntelliJ isn't liking when I try and set the property values inside of the FXML file and the scene builder doesn't show the property either.

Label Controller:

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();
    }
}

Label.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>

The attributes/children added to the <fx:include> element apply to the result of loading the other fxml, ie in this case the type of object created is VBox , not LabelController . VBox does not contain the properties you're trying to assign.

You cannot do this using fxml only. You'd need to use the initialize method of the controller to set the property values:

WelcomeSceneController

@FXML
private LabelController labelController;

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

WelcomeSceneBuilder.fxml

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

You could use the Custom Component approach though which would make the controller and node the same object allowing you to make assignments like these. Lacking inso about the responsibility of the node, I'm keeping LabelController , but of course you should choose a better name.

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;}

    ...
}

Label.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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM