【问题标题】:(JFoenix) JFXTreeTableView how to display/group image + string in column?(JFoenix) JFXTreeTableView 如何在列中显示/分组图像+字符串?
【发布时间】:2017-12-18 17:56:10
【问题描述】:

我正在尝试获取一个 JFXTreeTableView 列来显示文本和图像,同时继续使用树分组功能。

我在演示之后对我的程序进行了建模,并且能够使基于 StringProperty 的列正常工作,但现在尝试添加 ObjectProperty<Label> 列却无法正常工作。谁能给我一个使用 JFXTreeTableView 和除原始或字符串以外的任何内容(即使用 ObjectProperty<?> 的内容)的列示例吗?

编辑:我刚刚在这方面取得了一些进展,通过使用 HBox 作为我能够让我的图像和文本显示的列。

下面是我用来实现这一目标的代码...

在我的单元格对象中:

public final class TestObj extends RecursiveTreeObject<TestObj> {
        private final ObjectProperty<HBox> source;

        public TestObj(String source) {
                ImageView iv = new ImageView();
                HBox hbox = new HBox();
                hbox.setSpacing(10);
                VBox vbox = new VBox();
                Label l = new Label(source);
                vbox.getChildren().add(l);
                iv.setFitHeight(20);
                iv.setFitWidth(20);
                iv.setImage(new Image("/images/test.png"));
                l.setGraphic(iv);
                hbox.getChildren().addAll(vbox);
                this.source = new SimpleObjectProperty<>(hbox);
        }

        // ... getters & setters
}

在我的控制器中:

public void initialize(URL location, ResourceBundle resources) {
        JFXTreeTableColumn<TestObj, HBox> srcColumn = new JFXTreeTableColumn<>("Source");
        srcColumn.setPrefWidth(150);
        srcColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<TestObj, HBox> x) ->
        srcColumn.validateValue(x) ? x.getValue().getValue().sourceProperty() : srcColumn.getComputedValue(x));

        //... reset of table setup code
}

现在的问题是列不能正确分组!也就是说:每行的图像和文本可能完全相同,但不会折叠成一个组。相反,它会折叠成许多组,每个组都有一个元素。这让我觉得表格如何比较单元格是问题所在......也许我需要在某个地方覆盖一个方法?

编辑 2: 现在,使用下面的代码,可以进行分组,并且可以正确隐藏未分组的节点。此外,应用 James_D 注释将 GUI 元素重新定位到数据类之外。当前的问题(在上面的段落中概述)如图所示。 A和图。 B.

数据对象:

public final class TestObj extends RecursiveTreeObject<TestObj> {
        //inapplicable vars omitted from this class
        //so don't ask why there's just an inner class here ;)
        private final ObjectProperty<Register> source;
        private final ObjectProperty<Register> destination;

        public TestObj(String src, String srcPort, String srcCountry, String dst, String dstPort, String dstCountry) {
                this.source = new SimpleObjectProperty<>(new Register(src, srcPort, srcCountry));
                this.destination = new SimpleObjectProperty<>(new Register(dst, dstPort, dstCountry));
        }

        // ... getters & setters

        public class Register {
                private final String address;
                private final String port;
                private final String country;

                public Register(String address, String port, String country) {
                    this.address = address;
                    this.port = port;
                    this.country = country;
                }

                //getters ...
         }
}

控制器:

public void initialize(URL location, ResourceBundle resources) {
        JFXTreeTableColumn<TestObj, TestObj.Register> srcColumn = new JFXTreeTableColumn<>("Source");
        srcColumn.setPrefWidth(150); srcColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<TestObj, TestObj.Register> x) ->
            srcColumn.validateValue(x) ? x.getValue().getValue().sourceProperty() : srcColumn.getComputedValue(x));
    srcColumn.setCellFactory(new Callback<TreeTableColumn<TestObj, TestObj.Register>, TreeTableCell<TestObj, TestObj.Register>>() {
        @Override
        public TreeTableCell<TestObj, TestObj.Register> call(TreeTableColumn<TestObj, TestObj.Register> param) {
            return new JFXTreeTableCell<TestObj, TestObj.Register>() {
                ImageView iv = new ImageView();
                @Override
                protected void updateItem(TestObj.Register item, boolean empty) {
                    if(item != null) {
                        HBox hbox = new HBox();
                        hbox.setSpacing(10);
                        VBox vbox = new VBox();
                        Label l = new Label(item.getAddress() + ":" + item.getPort());
                        vbox.getChildren().add(l);
                        iv.setFitHeight(20);
                        iv.setFitWidth(20);
                        iv.setImage(new Image("/flags/" + item.getCountry() + ".png"));
                        l.setGraphic(iv);
                        hbox.getChildren().addAll(vbox);
                        setGraphic(hbox);
                    } else {
                        setGraphic(null);
                    }
                }
            };
        }
    });
        //... above duplicated for dstColumn
        //... reset of table setup code
}

图。 A - 展示表格的初始视图(这里一切正常)

图。 B - 显示不正确的分组(应该有 3 个组,每个组都有节点)

【问题讨论】:

  • 您似乎混淆了这方面的不同部分。您的数据类 (TestObj) 不应包含对任何 UI 组件的任何引用(例如 ImageViewHBox)。它应该只包含 data。如果要在列中自定义显示,请使用 cellFactory 生成自定义单元格。这与TableView 的工作方式基本相同:有一个很好的教程here(单元工厂涵盖here)。
  • 这个问题不再是简单地在表格中渲染图像。我现在有了,问题在于 JFXTreeTableView 的分组功能无法与我的对象列正常工作。似乎存在与 validateValue 方法相关的问题。附带说明一下,我确实更正了我的代码,将 UI 组件从数据类移动到 updateItem() 方法的覆盖中,但是分组问题仍然存在。
  • 好的,那么您希望我们帮助您诊断我们看不到的代码吗?
  • 好点!添加了更新...

标签: java javafx jfoenix


【解决方案1】:

在查看了 JFoenix 源代码后,我意识到幕后没有神奇的比较器……在我的数据对象中,我只需要重写 equals 和 hashCode 方法来考虑复杂对象的变量。

在这种情况下:

@Override
public boolean equals(Object o) {
    if(o == this)
        return true;
    if(!(o instanceof Register))
        return false;
    Register r = (Register)o;
    return Objects.equals(address, r.address) 
        && Objects.equals(port, r.port) 
        && Objects.equals(country, r.country);
}

@Override
public int hashCode() {
    return Objects.hash(address, port, country);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-20
    • 2021-10-09
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    相关资源
    最近更新 更多