Ответ 1
Подход к решению
Я советую использовать cell factory для решения этой проблемы.
listViewOfWords.setCellFactory(param -> new ListCell<Word>() {
@Override
protected void updateItem(Word item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null || item.getWord() == null) {
setText(null);
} else {
setText(item.getWord());
}
}
});
Пример приложения
import javafx.application.Application;
import javafx.collections.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;
public class CellFactories extends Application {
@Override
public void start(Stage stage) {
ObservableList<Word> wordsList = FXCollections.observableArrayList();
wordsList.add(new Word("First Word", "Definition of First Word"));
wordsList.add(new Word("Second Word", "Definition of Second Word"));
wordsList.add(new Word("Third Word", "Definition of Third Word"));
ListView<Word> listViewOfWords = new ListView<>(wordsList);
listViewOfWords.setCellFactory(param -> new ListCell<Word>() {
@Override
protected void updateItem(Word item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null || item.getWord() == null) {
setText(null);
} else {
setText(item.getWord());
}
}
});
stage.setScene(new Scene(listViewOfWords));
stage.show();
}
public static class Word {
private final String word;
private final String definition;
public Word(String word, String definition) {
this.word = word;
this.definition = definition;
}
public String getWord() {
return word;
}
public String getDefinition() {
return definition;
}
}
public static void main(String[] args) {
launch(args);
}
}
Замечания по реализации
Хотя вы можете переопределить toString в своем классе Word, чтобы предоставить строковое представление слова, предназначенного для представления в вашем ListView, я бы рекомендовал предоставить ячейку factory в ListView для извлечения данных вида из объекта слова и представление его в вашем ListView. Используя этот подход, вы получаете разделение проблем, поскольку вы не привязываете графическое представление своего объекта Word к нему текстовым методом toString; поэтому toString может продолжать иметь другой вывод (например, полную информацию о полях Word с именем слова и описанием для целей отладки). Кроме того, ячейка factory более гибкая, так как вы можете применять различные графические узлы для создания визуального представления ваших данных за пределы простой текстовой строки (если вы хотите это сделать).
Кроме того, в качестве стороннего я рекомендую сделать объекты Word неизменяемыми объектами, удалив их сеттеры. Если вам действительно нужно изменить сами слова-объекты, тогда лучший способ справиться с ними - открыть видимые свойства для полей объекта. Если вы также хотите, чтобы ваш пользовательский интерфейс обновлялся по мере изменения наблюдаемых свойств ваших объектов, вам необходимо, чтобы ваши ячейки списка знали об изменениях связанных элементов, прослушивая их изменения (что довольно сложно в этом дело). Обратите внимание, что список, содержащий слова, уже наблюдается, и ListView позаботится об обработке изменений в этом списке, но если вы изменили определение слова для экземпляра в отображаемом объекте слова, тогда ваше представление списка не подберет изменения в определение без соответствующей логики слушателя в ячейке ListView factory.