【问题标题】:TableView combobox display issues after scrolling滚动后 TableView 组合框显示问题
【发布时间】:2016-11-01 00:14:46
【问题描述】:

滚动后我遇到了显示问题。我的movieSubtitleTableColumn 单元格中的一些组合框应该是空的,它们填充了来自其他组合框的相同项目和值。此外,在滚动之前正确填充的组合框即使在滚动之后也会保留其正确的项目和值。 因此,由于某种原因,问题仅发生在空的。

控制器:

@FXML
private TableView<Movie> moviesTableView;
@FXML
private TableColumn<Movie, String> movieTitleTableColumn;
@FXML
private TableColumn<Movie, Subtitle> movieSubtitleTableColumn;

private ObservableList<Movie> movieList;

private void setupTableView(List<Movie> movieList) {
    this.movieList = FXCollections.observableList(movieList);
    moviesTableView.getItems().addAll(this.movieList);
    movieTitleTableColumn.setCellValueFactory(c -> new SimpleStringProperty(c.getValue().getMovieFile().getName()));
}

private void populateSubtitleChoiceBox() {
    if (!movieList.isEmpty()) {
        movieSubtitleTableColumn.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue().getMovieSubtitle()));
        movieSubtitleTableColumn.setCellFactory(col -> {
            ComboBox<SubtitleInfo> combo = new ComboBox<>();
            combo.setMaxWidth(Double.MAX_VALUE);
            combo.setConverter(
                    new StringConverter<SubtitleInfo>() {
                        @Override
                        public String toString(SubtitleInfo subtitleInfo) {
                            if (subtitleInfo == null) {
                                return null;
                            } else {
                                return subtitleInfo.getFileName();
                            }
                        }
                        @Override
                        public SubtitleInfo fromString(String s) {
                            return null;
                        }
                    });

            TableCell<Movie, Subtitle> cell = new TableCell<Movie, Subtitle>() {
                @Override
                protected void updateItem(Subtitle subInfo, boolean empty) {
                    super.updateItem(subInfo, empty);
                    if (empty) {
                        setGraphic(null);
                    } else {
                        if (subInfo != null) {
                            combo.getItems().setAll(subInfo.getSubtitleList());
                            combo.setValue(subInfo.getSubtitleSelected());
                        }
                        setGraphic(combo);
                    }
                }
            };

            combo.valueProperty().addListener((obs, oldValue, newValue) ->
                    cell.getItem().setSubtitleSelected(newValue));

            return cell;
        });
    }
}

型号:

public class Movie {
    private File movieFile;
    private Subtitle movieSubtitle;
    private BooleanProperty movieSubDownload = new SimpleBooleanProperty(false);
    //getters setters
}

public class Subtitle {
    private List<SubtitleInfo> subtitleList = new ArrayList<>();
    private SubtitleInfo subtitleSelected;
    //getters setters
}

在调用 populateSubtitleChoiceBox() 之前,我像这样更新我的电影列表:

for (Movie movie : movieList) {
   //do stuff
   movie.setMovieSubtitle(subtitle);
}
populateSubtitleChoiceBox();

截图:

Before scrolling (Correct Display)

After scrolling (Comboboxes that were supposed to be empty they are not anymore)

编辑: 目前我已经通过将图形设置为 null 来掩盖问题:

        TableCell<Movie, Subtitle> cell = new TableCell<Movie, Subtitle>() {
            @Override
            protected void updateItem(Subtitle subInfo, boolean empty) {
                super.updateItem(subInfo, empty);
                if (empty || subInfo == null || subInfo.getSubtitleList().isEmpty()) {
                    setGraphic(null);
                } else {
                    combo.getItems().setAll(subInfo.getSubtitleList());
                    combo.setValue(subInfo.getSubtitleSelected());
                    setGraphic(combo);
                }
            }
        };

虽然我仍然不知道如何正确修复它以及为什么会发生这种情况。如果您需要我的代码的任何其他部分,请告诉我。谢谢

【问题讨论】:

    标签: java javafx


    【解决方案1】:

    当您的单元格被重复使用时(例如在滚动期间),对updateItem(...) 方法的调用将重复调用

    combo.getItems().addAll(...);
    

    在同一个组合框上,因此您只需将越来越多的元素添加到组合框的项目列表中。您应该每次都替换所有项目,因此只需将该方法调用替换为对 setAll(...) 的调用:

    combo.getItems().setAll(subInfo.getSubtitleInfoObservableList());
    

    【讨论】:

    • James 我已经尝试过了。它仍然像以前一样行事。还有什么可能是错的?实际上,应该是空的组合框,他们从其他正确的组合框中获取他们的项目
    • @DeckardCain 那时不确定。您可能需要写一个minimal reproducible example 并编辑您的问题以包含它。您发布的代码没有其他明显错误。
    • 我会尽力的。请原谅我的问题结构。
    猜你喜欢
    • 1970-01-01
    • 2013-03-04
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 1970-01-01
    相关资源
    最近更新 更多