如何在FXML中的对象元素之前创建对象的引用?

时间:2016-07-21 01:45:20

标签: javafx fxml

我在FXML文档中定义了两个对象。我希望他们中的一个有一个参考,也是在FXML中定义的另一个。具有另一个对象的对象的FXML元素在文档中排在第一位。通过javafx.fxml.FXMLLoader加载时,该属性保持未分配状态。如果具有另一个对象的对象位于第二个,则 分配属性。有没有办法将对象引用分配给FXML文档中较早出现的对象的属性?

这是一个最小的完整可验证示例。引用另一个并且在它之前的对象没有分配其属性,并且在测试时它为空。它引用的对象之后的那个获取它的属性,并打印出对象的toString()。

issue.fxml:     

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import test.control.*?>

<HBox xmlns:fx="http://javafx.com/fxml/1" id="pane1" prefHeight="400.0" prefWidth="600.0">
    <FriendlyButton fx:id="priorObjectReference" friend="$normalButton" />
    <Button fx:id="normalButton" />
    <FriendlyButton fx:id="subsequentObjectReference" friend="$normalButton" />
</HBox>

FXMLIssue.java,加载到FXML以上并尝试打印对象引用:

import java.io.IOException;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.stage.Stage;
import test.control.FriendlyButton;

public class FXMLIssue extends Application {
    @Override
    public void start(Stage stage) {
        Parent container = null;
        try {
            container = FXMLLoader.load(Paths.get("issue.fxml").toUri().toURL());
        } catch (IOException ex) {
            Logger.getLogger(FXMLIssue.class.getName()).log(Level.SEVERE, "Failed to load file.", ex);
            Platform.exit();
        }

        FriendlyButton priorObjectReference = (FriendlyButton) container.lookup("#priorObjectReference");
        System.out.println(priorObjectReference.getFriend() == null ? "priorObjectReference's friend property wasn't loaded from FXML" : "priorObjectReference's friend is: " + priorObjectReference.getFriend().toString());

        FriendlyButton subsequentObjectReference = (FriendlyButton) container.lookup("#subsequentObjectReference");
        System.out.println(subsequentObjectReference.getFriend() == null ? "subsequentObjectReference's friend property wasn't loaded from FXML" : "subsequentObjectReference's friend is: " + subsequentObjectReference.getFriend().toString());

        Platform.exit();
    }

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

FriendlyButton.java,只是一个具有引用FXML中另一个对象的属性的类:

package test.control;

import javafx.scene.control.Button;

public class FriendlyButton extends Button {
    private Button mFriend;

    public Button getFriend() {
        return mFriend;
    }

    public void setFriend(Button friend) {
        mFriend = friend;
    }
}

2 个答案:

答案 0 :(得分:3)

<HBox xmlns:fx="http://javafx.com/fxml/1" id="pane1" prefHeight="400.0" prefWidth="600.0">
    <fx:define>
        <Button fx:id="normalButton" />
    </fx:define>
    <FriendlyButton fx:id="priorObjectReference" friend="$normalButton" />
    <fx:reference source="normalButton" />
    <FriendlyButton fx:id="subsequentObjectReference" friend="$normalButton" />
</HBox>

答案 1 :(得分:0)

另一种解决方案是使用JavaFX属性重写FriendlyButton类,并至少使用expression binding${})作为第一个引用:

<FriendlyButton fx:id="priorObjectReference" friend="${normalButton}" />
<Button fx:id="normalButton"/>
<FriendlyButton fx:id="subsequentObjectReference" friend="$normalButton" />

// FriendlyButton.java:

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.control.Button;

public class FriendlyButton extends Button {
    private ObjectProperty<Button> friend = new SimpleObjectProperty<>();
    public final Button getFriend() { return friend.get(); }
    public final void setFriend(Button value) { friend.set(value); }
    public final ObjectProperty<Button> friendProperty() { return friend; }
}