Только контроллер имеет соответствующие поля. Ваш класс SteeringWheel
не является контроллером, поэтому аннотированные поля @FXML
не вводятся. Объекты, которые вы намереваетесь ввести в эти поля, помещаются в список children
, поэтому вы могли бы получить к ним доступ там. Однако кажется, что вы хотите, чтобы SteeringWheel
был его собственным компонентом, где два Circle
s и Label
присутствуют всегда , независимо от того, как используется SteeringWheel
, так что это не так. Имеет смысл попытаться определить детей в отдельном месте.
Поскольку вы расширяете Region
, вы можете рассмотреть возможность использования fx:root
:
import java.io.IOException;
import java.io.UncheckedIOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Circle;
public class SteeringWheel extends Pane {
@FXML private Label myLabel;
@FXML private Circle innerCircle;
@FXML private Circle backgroundCircle;
public SteeringWheel() {
FXMLLoader loader = new FXMLLoader(/* location */);
loader.setRoot(this);
loader.setController(this);
try {
loader.load();
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
}
@FXML
private void initialize() {
// perform any initialization, if needed
}
@Override
public void layoutChildren() {
// Note: I didn't implement checking if the nodes are managed
// before laying them out. You may wish to add that
// behavior.
// The following will always keep the Circles in the center
// of the Pane. However, it does this by setting the layout[X|Y]
// properties rather than the center[X|Y] properties (as you're
// doing).
double x = snappedLeftInset();
double y = snappedTopInset();
double w = getWidth() - snappedRightInset() - x;
double h = getHeight() - snappedBottomInset() - y;
positionInArea(innerCircle, x, y, w, h, -1, HPos.CENTER, VPos.CENTER);
positionInArea(backgroundCircle, x, y, w, h, -1, HPos.CENTER, VPos.CENTER);
// Layout the Label in the top-left corner
layoutInArea(myLabel, x, y, w, h, -1, HPos.LEFT, VPos.TOP);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.shape.Circle?>
<fx:root type="javafx.scene.layout.Pane" xmlns="http://javafx.com/javafx/9.0.1"
xmlns:fx="http://javafx.com/fxml/1">
<Label fx:id="myLabel" text="Hello, World!"/>
<Circle fx:id="backgroundCircle" radius="30" fill="BLACK"/>
<Circle fx:id="innerCircle" radius="25" fill="FIREBRICK"/>
</fx:root>
Примечание: Я расширил Pane
вместо Region
. Первый уже расширяет последний и уже вносит сделанные вами изменения (т. Е. Делает метод #getChildren()
publi c и добавляет аннотацию @DefaultProperty("children")
).
Примечание : Я перебил #layoutChildren()
, чтобы ваши круги оставались в центре независимо от того, с какими размерами заканчивается родитель. Однако может быть проще просто обернуть их в какой-то другой макет, например StackPane
.
Тогда вы просто используете SteeringWheel
в другом файле F XML:
<BorderPane xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/9.0.1" fx:controller="view.WindowController">
<center>
<VBox prefHeight="200" prefWidth="200" BorderPane.alignment="CENTER">
<children>
<SteeringWheel fx:id="steeringWheel"/>
</children>
</VBox>
</center>
.....