Я создал пользовательский компонент TableBlock. Он состоит из Label и TableView. TableViewcan может иметь, например, от 1 до 1000 строк. Количество строк определяется параметром «rowsFromPrefs» в файле FXML. Этот параметр необходим для создания TableView. TableView полностью создается кодом JAva, в fxml - только его тег и параметр с количеством строк.Задайте настраиваемые свойства FXML в качестве параметров для настраиваемого компонента javafx
Как я знаю, когда JavaFX создает компонент FXML, он сначала вызывает конструктор, затем @FXML аннотированные поля, а затем запускает метод initialize().
В моем случае при запуске initialize() переменные rowsFromPrefs по-прежнему равны нулю! Но, если я попытаюсь получить значение rowsFromPrefs из другого потока (а не JavaFX-launcher), я вижу, что он определен = «2», как и должно быть.
Так что я не могу понять, в какой момент Java назначает объектные параметры из файла FXML. Как передать параметр из файла fxml в объект, когда он создается.
Я видел аннотацию @NamedArg для параметров конструктора. Это единственный способ передачи параметра при создании объектов?
контроллер может определить метод Initialize(), который будет вызываться один раз> исполнителем контроллера, когда содержание связанного с ним документа, которые> были полностью загружены:
TableBlock.java
public class TableBlock extends VBox{
@FXML
private String rowsFromPrefs;
@FXML
private Label label;
public TableBlock() {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("TableBlock.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
}
@FXML
public void initialize() {
this.table = createTable(rowsFromPrefs);
}
public String getRowsFromPrefs() {
System.out.println("getRowsFromPrefs");
return rowsFromPrefs;
}
public void setRowsFromPrefs(String rowsFromPrefs) {
this.rowsFromPrefs = rowsFromPrefs;
}
}
TableBlock.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import ru.laz.model.controls.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<?import ru.laz.model.controls.tableblock.*?>
<fx:root type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label text="Label" />
</children>
</fx:root>
View.java
public class View extends Application {
Parent root = null;
private Scene scene;
@Override
public void init() {
try {
root = FXMLLoader.load(getClass().getResource("View.fxml"));
root.requestLayout();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void start(final Stage stage) throws Exception {
scene = new Scene(root, 640, 480, Color.LIGHTGRAY);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
View.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<?import ru.laz.model.controls.tableblock.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<TableBlock rowsFromPrefs="2" id="IDDQD"/>
</children>
</AnchorPane>
большое спасибо для подробного объяснения. NamedArg - это подходящее решение, как я думаю. – LazerJet