包含ListView更新的JavaFX TableView,CellValueFactory

包含ListView更新的JavaFX TableView,CellValueFactory,listview,javafx-8,Listview,Javafx 8,我确实有一台发动机,它的零件列表如下: 更新: 我更新了文本以提供一个示例 我想有一个包含2列(名称、部件)的引擎表视图。我希望parts列在TableCell中呈现为ListView,因此我覆盖该列的CellFactory import javafx.beans.property.ObjectProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStrin

我确实有一台发动机,它的零件列表如下:

更新: 我更新了文本以提供一个示例

我想有一个包含2列(名称、部件)的引擎表视图。我希望parts列在TableCell中呈现为ListView,因此我覆盖该列的CellFactory

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);
    } }

不会这样做,因为它将被包装,如果我在明细栏中更改零件,它不会更新明细栏视图中的零件。我需要创建一个回调函数,它将部件列表作为表单元格的可观察对象提供,但我不知道如何做到这一点。有人需要帮助吗?

您的
PartListCell
只需将其标签文本设置为与零件名称连接的引擎名称的当前值。如果单元格显示的零件发生更改,它将更新(
updateItem(…)
将再次调用),但单元格和标签都不会观察引擎的名称。因此,如果引擎的名称更改,单元格不知道它需要更新

修复方法只是将标签的文本绑定到适当的
StringExpression

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

    public PartListCell() {

    }

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

        name.textProperty().unbind();

        if(!empty && part != null) {
            name.textProperty().bind(part.getEngine().nameProperty().concat(" / ").concat(part.nameProperty()));
            setGraphic(name);
        } else {
            name.setText(null);
            setGraphic(null);
        }
    }
}
类PartListCell扩展了ListCell{ 私有标签名称=新标签(); 公共部分列表单元格(){ } @凌驾 受保护的void updateItem(部分,布尔值为空){ super.updateItem(部分,空); name.textProperty().unbind(); 如果(!empty&&part!=null){ name.textProperty().bind(part.getEngine().nameProperty().concat(“/”).concat(part.nameProperty()); 设置图形(名称); }否则{ name.setText(空); 设置图形(空); } } }
不是答案,评论太长:

仍然不能确定我是否正确理解了您的要求:但这里有一个提取器,它可以满足您的需求:

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

hmm。。。可能不太了解您的设置:表中项目的类型是什么?看起来像是行项目(发动机、零件)中的某个项目?如果是这样,您将需要table.items列表上的提取器,用于侦听零件的更改。如果没有,ol的程序:请提供一份SSCCE证明问题:-)@kleopatra i提供了上述示例,不幸的是,我不得不创建另外两个文件,因为我在创建属性值factoryunrelated时遇到了一个反射错误:您不需要CommitteHandler-automagics如果属性可写就这样做谢谢您的回答,我在上面提供了一个示例来说明我的问题是什么,我想我在确定之前没有明确说明,我现在明白了:我没有意识到列表单元格也需要显示引擎的名称。见更新。感谢詹姆斯的回答,我认为克利奥帕特拉的解决方案是我想要的,即使你的解决方案基本上更有效。但是如果我可以避免在这样一个详细的级别上进行绑定,我会选择extractorOh,这确实很好。是的,基本上就是这样,我没有意识到,我可以通过
获取父属性。get()
,它按照我的需要工作。
partsColumn.setCellValueFactory(new PropertyValueFactory<>("parts"));
class PartListCell extends ListCell<Part> {
    private Label name = new Label();

    public PartListCell() {

    }

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

        name.textProperty().unbind();

        if(!empty && part != null) {
            name.textProperty().bind(part.getEngine().nameProperty().concat(" / ").concat(part.nameProperty()));
            setGraphic(name);
        } else {
            name.setText(null);
            setGraphic(null);
        }
    }
}
Callback<Part, Observable[]> partsExtractor = part -> new Observable[] {
            part.nameProperty(), part.engineProperty().get().nameProperty() };