非 table 情况下的 FXML 迭代渲染

Iterative rendering in FXML in non-table case

下面 Vue 类标记中的迭代呈现(v-for 属性)的 FXML 等价物是什么?

<VBox>
    <HBox v-for="task of tasks">
        <Checkbox :checked="task.isComplete"></Checkbox>
        <VBox>
            <Label>{{ task.title }}</Label>
            <Label>{{ task.description }}</Label>
        </VBox>
    </HBox>
</VBox>

想要的显示:

我准备了以下ObservableList:

ObservableList<Task> tasks = FXCollections.observableArrayList();
tasks.add(new Task("Wake up", "... and fly."));
tasks.add(new Task("Wash face", "... with cold water."));

ObservableList 会对新增内容做出反应,您只需以某种方式以编程方式显示它,例如使用带有 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);
    }
}

有关更多信息,请参阅本文 details