【问题标题】:JavaFX TableView displays null valuesJavaFX TableView 显示空值
【发布时间】:2017-10-10 16:32:25
【问题描述】:

我最近遇到了一个有趣的问题。我有一个包含 1 个 int 和 3 个 String 列的表。我已经为表格实现了过滤,除了一个小问题外,它工作得非常好:只要有至少一个过滤结果(但少于可见行的数量),int 列就会将空值显示为空行的值。但是,如果找到的匹配数量超过可见行数,则不会添加空值(即使具有滚动功能)。最好用图片来描述:

过滤不存在​​的值不显示空值:

过滤代码:

    FilteredList<Word> filteredData = new FilteredList<>(masterData,e->true);
    SortedList<Word> sortedData = new SortedList<>(filteredData);
    sortedData.comparatorProperty().bind(table.comparatorProperty());
    table.setItems(sortedData);
    TextField filter = new TextField();
    filter.setPromptText("Filter");
    filter.textProperty().addListener((observableValue,oldValue,newValue)->{
        filteredData.setPredicate((Predicate<? super Word>) word->{
            if(word.getAllCz().toLowerCase().contains(newValue.toLowerCase()))return true;
            else if(word.getAllEng().toLowerCase().contains(newValue.toLowerCase()))return true;
            else if(String.valueOf(word.getUnitNo()).equals(newValue))return true;
            else return false;
        });
    });

CellValue 工厂:

    column.setCellValueFactory(new PropertyValueFactory<>(data));
    column.setCellFactory(tc-> {
        TableCell<Word, Integer> cell = new TableCell<>();
        Text text = new Text();
        cell.setGraphic(text);
        text.setTextAlignment(TextAlignment.CENTER);
        text.setStyle("-fx-fill: -fx-text-background-color;");
        text.setFontSmoothingType(FontSmoothingType.LCD);
        text.wrappingWidthProperty().bind(column.widthProperty().subtract(5));
        text.textProperty().bind(cell.itemProperty().asString());
        return cell;  
    });

【问题讨论】:

  • 请包含设置第一列 cellValueFactory 的代码。
  • 您在该列上有自定义单元工厂吗?如果是这样,请发布它。旁白:您是否意识到您正在不断地向文本字段的文本属性添加越来越多的侦听器?最终这将使应用程序停止。每次文本更改时也无需创建新的排序列表。
  • 我添加了一个 cellValueFactory。 James_D 感谢您指出这一点。我还是新手,所以我没有注意到。
  • @kleopatra 我不太明白你的意思。能详细解释一下吗?
  • 嗯,由于 james_d 的回答,我想我已经做到了。我已经编辑了问题以反映我现在拥有的代码。

标签: java javafx filter null


【解决方案1】:

如果单元格为空,则其项目将为null,而itemProperty().asString() 将评估为包含文字“null”的字符串(类似于将空值传递给PrintStream)。您的绑定需要将空单元格视为特殊情况:

column.setCellFactory(tc-> {
    TableCell<Word, Integer> cell = new TableCell<>();
    Text text = new Text();
    cell.setGraphic(text);
    text.setTextAlignment(TextAlignment.CENTER);
    text.setStyle("-fx-fill: -fx-text-background-color;");
    text.setFontSmoothingType(FontSmoothingType.LCD);
    text.wrappingWidthProperty().bind(column.widthProperty().subtract(5));
    text.textProperty().bind(Bindings.createStringBinding(() -> {
        if (cell.isEmpty()) {
            return null ;
        } else {
            return cell.getItem().toString();
        }
    }, cell.emptyProperty(), cell.itemProperty()));
    return cell;  
});

或者你需要覆盖updateItem():

column.setCellFactory(tc-> {
    TableCell<Word, Integer> cell = new TableCell<>() {
        private Text text = new Text();
        {
            this.setGraphic(text);
            text.setTextAlignment(TextAlignment.CENTER);
            text.setStyle("-fx-fill: -fx-text-background-color;");
            text.setFontSmoothingType(FontSmoothingType.LCD);
            text.wrappingWidthProperty().bind(column.widthProperty().subtract(5));
        }

        @Override
        protected void updateItem(Integer item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                text.setText(null);
            } else {
                text.setText(item.toString());
            }
        }
    };
    return cell;  
});

【讨论】:

  • 非常感谢,我使用了第二种方法,因为第一种方法在 createStringBinding(() 处给了我一个错误。我可以再问一件事:如果一个带有整数项的空单元格被评估为“null”字符串,为什么我的空字符串单元格不做同样的事情?
  • 修复了绑定版本的错误。我无法真正评论我看不到的代码行为;您是否也在字符串列的单元格绑定中使用了asString()(这很奇怪,因为它们已经是字符串了)。
  • 字符串的代码几乎相同,除了绑定时我有text.textProperty().bind(cell.itemProperty());
  • @zotmer 所以这就解释了,不是吗?
  • 哦,是的,我现在终于明白了。方法asString() 将空值转换为字符串“null”。由于我们没有在其余列中使用asString(),因此正确传入了空值并且没有显示任何内容。再次感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-11
  • 1970-01-01
  • 2018-11-13
  • 2016-09-02
  • 2014-07-28
  • 2015-12-15
相关资源
最近更新 更多