包含ListView更新,CellValueFactory的JavaFX TableView [英] JavaFX TableView containing ListView Updates, CellValueFactory

查看:101
本文介绍了包含ListView更新,CellValueFactory的JavaFX TableView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我确实有一个引擎,其中包含以下列表中的零件:

I do have an engine which contains parts in a list like:

更新: 我更新了文字以提供示例

我想拥有一个包含2列(名称,零件)的引擎TableView.我希望将Column部件呈现为TableCell中的ListView,因此我覆盖了该列的CellFactory.

I would like to have a TableView of engines which contains 2 Columns (name, parts). I want the parts Column to be rendered as a ListView within the TableCell, therefore i override the CellFactory of the column.

import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty;

public class Part {
    private final SimpleStringProperty name = new SimpleStringProperty("");
    // Reference to the parent engine
    private final ObjectProperty<Engine> engine= new SimpleObjectProperty<>(null);

    public Part(String name, Engine engine) {
        this.setName(name);
        this.setEngine(engine);
    }

    public ObjectProperty<Engine> engineProperty() {
        return engine;
    }

    public Engine getEngine() {
        return engine.get();
    }

    public void setEngine(Engine engine) {
        this.engine.set(engine);
    }

    public SimpleStringProperty nameProperty() {
        return name;
    }

    public String getName() {
        return name.get();
    }

    public void setName(String name) {
        this.name.set(name);
    } }

引擎类:

import javafx.beans.Observable;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.util.Callback;

public class Engine {
    private final SimpleStringProperty name = new SimpleStringProperty("");

    Callback<Part, Observable[]> partsExtractor = part -> new Observable[] {
            part.nameProperty(),
            part.engineProperty()
    };

    private final ObservableList<Part> parts = FXCollections.observableArrayList(partsExtractor);

    public Engine(String name) {
        this.setName(name);
    }

    public void setName(String name) {
        this.name.set(name);
    }

    public String getName() {
        return name.get();
    }

    public SimpleStringProperty nameProperty() {
        return name;
    }

    public ObservableList<Part> getParts() {
        return parts;
    }
}

应用程序:

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;

/**
 * If you edit the field name of the engine on the table the changed name does not reflect on the listView within the
 * table cell, it should actually show the new name of the engine
 */

class PartListCell extends ListCell<Part> {
    private Label name = new Label();

    public PartListCell() {

    }

    @Override
    protected void updateItem(Part part, boolean empty) {
        super.updateItem(part, empty);

        if(!empty && part != null) {
            name.setText(part.getEngine().getName() + " / " + part.getName());
            setGraphic(name);
        } else {
            setGraphic(null);
        }
    }
}

class PartsTableCell extends TableCell<Engine, ObservableList<Part>> {
    private final ListView<Part> listView = new ListView<>();

    public PartsTableCell() {
        listView.setCellFactory(listView -> new PartListCell());
    }

    @Override
    protected void updateItem(ObservableList<Part> parts, boolean empty) {
        if(!empty && parts != null){
            listView.setItems(parts);
            setGraphic(listView);
        } else {
            setGraphic(null);
        }
    }
}

public class Main extends Application {

    Callback<Engine, Observable[]> engineExtractor = engine -> new Observable[] {
            engine.nameProperty(),
    };

    private final ObservableList<Engine> engines = FXCollections.observableArrayList(engineExtractor);

    public Main() {
        Engine engine = new Engine("Engine-1");
        Part part1 = new Part("Part-1", engine);
        Part part2 = new Part("Part-1", engine);

        engine.getParts().addAll(part1, part2);

        engines.add(engine);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        StackPane root = new StackPane();

        TableColumn<Engine, String> nameColumn = new TableColumn<>("Name");
        TableColumn<Engine, ObservableList<Part>> partsColumn = new TableColumn<>("Parts");

        // Set the Cell Factories
        nameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        // Make an editable text field
        nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        nameColumn.setOnEditCommit(event -> event.getTableView().getItems().get(
                event.getTablePosition().getRow()).setName(event.getNewValue()));

        partsColumn.setCellFactory(param -> new PartsTableCell());
        partsColumn.setCellValueFactory(new PropertyValueFactory<>("parts"));

        TableView<Engine> tableView = new TableView<>(engines);
        tableView.setEditable(true);
        tableView.getColumns().add(nameColumn);
        tableView.getColumns().add(partsColumn);

        // Set the stage
        root.getChildren().add(tableView);
        primaryStage.setScene(new Scene(root, 400, 400));
        primaryStage.show();
    }
}

但是我如何创建CellValueFactory,因为一个

But how do i create the CellValueFactory, because a

partsColumn.setCellValueFactory(new PropertyValueFactory<>("parts"));

不会这样做,因为它将被包裹起来,如果我在零件列表中更改零件,它不会更新零件listView中的零件.我需要创建一个回调,该回调提供表单元可观察到的零件列表,但是我不知道该怎么做.有人需要帮助吗?

wont do it since it will get wrapped and if i change a part within the parts list it does not update the parts in the parts listView. I need to create a Callback which provides the list of parts as an observable to the Table Cell, but i do not know how to do this. Anyone for help?

推荐答案

没有答案,评论太久了

仍然不确定我是否正确理解了您的要求:但这是一个提取器,可以执行我认为您想要的操作:

Still not quite certain if I understand your requirement correctly: but here's an extractor that does what I think you want:

Callback<Part, Observable[]> partsExtractor = part -> new Observable[] {
            part.nameProperty(), part.engineProperty().get().nameProperty() };

这篇关于包含ListView更新,CellValueFactory的JavaFX TableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆