I have an application that takes in an FXML to load. The FXML is external to the application (not made by the developer).
The application has a server connection to get telemetry data.
I need to update nodes based on these telemetry data. In that regard I have made a NodeData user data object that designers of FXML can add to each Node in the FXML
FXML userData showed inline for demonstration
<AnchorPane fx:id="rootPane" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1">
<Label fx:id="label1">
<userData>
<NodeData>
<queries>
<FXCollections fx:factory="observableArrayList">
<String fx:value="select name from TABLE_1" />
<String fx:value="select title from TABLE_2 />
</FXCollections>
</queries>
</NodeData>
</userData>
</Label>
</AnchorPane>
The Java user data objects
/** Node DAO */
public class NodeData {
private ObservableList<NodeQuery> queries;
public ObservableList<NodeQuery> getQueries() {
return queries;
}
public void setQueries(ObservableList<NodeQuery> queries) {
this.queries = queries;
}
}
public class NodeQuery {
private String query;
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.queries = queries;
}
}
I planned in having NodeData sending the queries and receiving the response.
When the response is received I wanted to update the Node. I am not quite sure how I would do it. There is no Observable on user data back to the node I can listen to.
One solution:
Perhaps I could have the controller do the work. In @FXML initialize I could iterate through the rootPane I have access to, find all nodes, retrieve its NodeData, send the queries. When received update the node. However that seems a little messy.
@FXML
private void initialize() {
Stack<Node> nodes = new Stack<>();
nodes.addAll(rootPane.getChildren());
while (!nodes.empty()) {
Node node = nodes.pop();
Object userData = node.getUserData();
if (userData instanceof NodeData) {
NodeData nodeData = (NodeData) userData;
// Do work on nodeData.
}
if (node instanceof Pane) {
Pane pane = (Pane) node;
nodes.addAll(pane.getChildren());
} else if (node instanceof TitledPane) {
TitledPane titledPane = (TitledPane) node;
Node content = titledPane.getContent();
if (content instanceof Pane) {
Pane pane = (Pane) content;
nodes.addAll(pane.getChildren());
}
}
}
}
I would like an opinion on this design strategy, if there perhaps is a better solution here?