Reputation: 963
So, here's an example fxml from yfiles developer's guide (not that important actually):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import com.yworks.yfiles.drawing.NodeTemplate?>
<NodeTemplate fx:id="templateNode" style="-fx-background-color: darkblue"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<VBox alignment="CENTER">
<Label fx:id="firstName" text="${templateNode.item.tag.firstName}"
textFill="${templateNode.styleTag.firstNameColor}" />
<Label fx:id="lastName" text="${templateNode.item.tag.lastName}"
textFill="${templateNode.styleTag.lastNameColor}" />
</VBox>
</NodeTemplate>
templateNode.item.tag is an object of Person class:
public class Person {
private final String firstName;
private final String lastName;
public Person(String firstName, String lastName){
this.firstName = firstName; this.lastName = lastName;
}
public String getFirstName() {return firstName;}
public String getLastName() {return lastName;}
}
Is it possible inside fxml to:
a) perform some view-logic (that's how i call it) inside fxml? For example to make first label's text to be set to templateNode.item.tag.firstName if and only if it's length is > 10 and "whatever" otherwise?
b) at least specifically iterate over a collection from model?
Imagine templateNode.item.tag is a list of Person objects.
For example in pydjanvaFX (which is django-enhanced-templating inside javaFX, language i invented on the occasion of writing this question) language i can write something like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import com.yworks.yfiles.drawing.NodeTemplate?>
<NodeTemplate fx:id="templateNode" style="-fx-background-color: darkblue"
xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<VBox alignment="CENTER">
{% for i, model in enumerate(templateNode.item.tag) %}
<Label fx:id="firstName#${i}" text="${model.firstName}"
textFill="${templateNode.styleTag.firstNameColor}" />
<Label fx:id="lastName#${i}" text="${model.lastName}"
textFill="${templateNode.styleTag.lastNameColor}" />
{% endfor %}
</VBox>
</NodeTemplate>
Upvotes: 2
Views: 471
Reputation: 18415
You may want to read Introduction to FXML and about Scripting in FXML.
The
<fx:script>
tag allows a caller to import scripting code into or embed script within a FXML file. Any JVM scripting language can be used, including JavaScript, Groovy, and Clojure, among others. Script code is often used to define event handlers directly in markup or in an associated source file, since event handlers can often be written more concisely in more loosely-typed scripting languages than they can in a statically-typed language such as Java.
However, I strongly advise against it. You want to find compile time errors, not runtime errors.
A brief example about how a script could look like, a label is added dynamically:
<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<VBox fx:id="root" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8">
<children>
<Button text="Button" />
<Label text="Label" />
</children>
<fx:define>
<Label fx:id="addedLabel" text="Label" />
</fx:define>
<fx:script>
addedLabel.setText('Added Label');
root.getChildren().add( addedLabel);
java.lang.System.out.println( "Children: " + root.getChildren().size());
</fx:script>
</VBox>
I won't go any deeper into this or lists or whatever scripting you want to do, because seriously: don't do it this way! Sooner or later you'll run into problems.
Upvotes: 2