Issue
What the FXML equivalent for iterative rendering (v-for
attribute) in below Vue-like markup?
<VBox>
<HBox v-for="task of tasks">
<Checkbox :checked="task.isComplete"></Checkbox>
<VBox>
<Label>{{ task.title }}</Label>
<Label>{{ task.description }}</Label>
</VBox>
</HBox>
</VBox>
The desired displaying:
I prepared the below ObservableList
:
ObservableList<Task> tasks = FXCollections.observableArrayList();
tasks.add(new Task("Wake up", "... and fly."));
tasks.add(new Task("Wash face", "... with cold water."));
Solution
ObservableList
will react to new additions, you just have to display it programmatically in some way, for example using a custom component with ListView
:
package sample;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Main extends Application {
static class Task{
String title, description;
boolean done;
Task(String title, String description){
this.title = title;
this.description = description;
}
}
ListView<Task> list = new ListView<>();
ObservableList<Task> data = FXCollections.observableArrayList(
new Task("Wake up", "... and fly."),
new Task("Wash face", "... with cold water.")
);
@Override
public void start(Stage stage) {
VBox box = new VBox();
Scene scene = new Scene(box, 200, 200);
stage.setScene(scene);
stage.setTitle("ListViewSample");
box.getChildren().addAll(list);
VBox.setVgrow(list, Priority.ALWAYS);
list.setItems(data);
list.setCellFactory(list -> new TaskCell());
stage.show();
}
static class TaskCell extends ListCell<Task> {
@Override
public void updateItem(Task task, boolean empty) {
super.updateItem(task, empty);
if (task != null) {
CheckBox done = new CheckBox();
done.addEventHandler(MouseEvent.MOUSE_CLICKED, event -> { task.done = !task.done; });
done.setSelected(task.done);
HBox cell = new HBox(
done,
new VBox(new Label(task.title), new Text(task.description))
);
cell.setAlignment(Pos.CENTER_LEFT);
setGraphic(cell);
}
}
}
public static void main(String[] args) {
launch(args);
}
}
See this article for more details.
Answered By - nluk