我正在为我的测验申请编辑。
我有一个自定义ListCell<Question>
类,如下所示:
public class QuestionListCell extends ListCell<Question> {
private static final Logger LOGGER = Logger.getLogger(QuizLoader.class.getName());
@FXML HBox cellBox;
@FXML Label title;
@FXML GridPane answersGrid;
private FXMLLoader loader;
@Override
protected void updateItem(Question item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
}
else {
if (loader == null) {
loader = new FXMLLoader(getClass().getResource(QUESTION_LIST_CELL_FXML));
loader.setController(this);
try {
loader.load();
}
catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
}
addContent(item);
}
}
private void addContent(Question question) {
title.textProperty().bind(question.getQuestionTextProperty());
int answersSize = question.getAnswers().size();
for (int i = 0; i < answersSize; i++) {
int rowIndex = i / 2;
int colIndex = i % 2 == 0 ? 0 : 1;
Label answerLabel = new Label();
answerLabel.textProperty().bind(question.getAnswers().get(i).getAnswerTextProperty());
answerLabel.prefWidthProperty().bind(Bindings.divide(answersGrid.widthProperty(), 2));
answersGrid.add(answerLabel, colIndex, rowIndex);
}
final NumberBinding cellBoxWidth = Bindings.subtract(getListView().widthProperty(), 20);
cellBox.prefWidthProperty().bind(cellBoxWidth);
answersGrid.prefWidthProperty().bind(cellBoxWidth);
setGraphic(cellBox);
}
}
我在MainController
中设置了ListView,如下所示:
@FXML
private void onAddButtonClicked() {
LOGGER.log(Level.INFO, "addButton clicked.");
// quiz.getQuestions().add(quiz.getQuestions().get(0));
}
@FXML
private void onDeleteButtonClicked() {
LOGGER.log(Level.INFO, "deleteButton clicked.");
int index = listView.getSelectionModel().getSelectedIndex();
if (index >= 0) {
quiz.getQuestions().remove(index);
}
}
private void setUpQuestionsListView() {
listView.setCellFactory(listView -> new QuestionListCell());
listView.itemsProperty().bindBidirectional(quiz.getQuestionsProperty());
}
到目前为止,ListView看起来像这样:
但是,当我删除第一个(也是第一个)项目时,第二个项目的GridPane似乎覆盖在第一个项目上。
如果我在ListView中有更多元素,那么这不会发生,据我所知,只有剩下两个元素并且我删除了第一个元素。我做错了什么?
答案 0 :(得分:1)
添加行
answersGrid.getChildren().clear() ;
在addContent()
的开头(或者,如果您愿意,可以在updateItem()
中,在致电addContent()
之前)。
问题是你只为每个细胞加载一次FXML(这是一件好事);如果(何时)该单元格随后被重用,则在不更改updateItem()
引用的情况下再次调用answersGrid
,并且您可以向网格中添加更多子项而不删除原始子项。因此,当重复使用单元格时(例如通过滚动,或者当项目被删除并且其单元格被重用于另一个项目时),多个节点被添加到网格中的相同位置。
如上所述,从网格中删除现有标签将解决问题。