如何在 FXML 中的对象元素之前创建对对象的引用?
How do I create a reference to an object before the object's element in 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,只是一个 class 有一个 属性 引用 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;
}
}
<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>
另一种解决方案是用 JavaFX 属性 重写 FriendlyButton
class 并至少使用 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; }
}
我在 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,只是一个 class 有一个 属性 引用 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;
}
}
<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>
另一种解决方案是用 JavaFX 属性 重写 FriendlyButton
class 并至少使用 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; }
}