1. Введение
JavaFX — это мощный инструмент, предназначенный для создания пользовательского интерфейса приложения для различных платформ. Он предоставляет не только компоненты пользовательского интерфейса, но и различные полезные инструменты, такие как свойства и наблюдаемые коллекции.
Компонент ListView
удобен для управления коллекциями. А именно, нам не нужно было явно определять DataModel
или обновлять элементы ListView .
Когда в ObjervableList
происходит изменение , оно отражается в виджете ListView .
Однако для такого подхода требуется способ отображения наших пользовательских элементов в JavaFX ListView
. В этом руководстве описывается способ настройки внешнего вида объектов домена в ListView
.
2. Фабрика клеток
2.1. Поведение по умолчанию
По умолчанию ListView
в JavaFX использует метод toString()
для отображения объекта.
Таким образом, очевидный подход состоит в том, чтобы переопределить его:
public class Person {
String firstName;
String lastName;
@Override
public String toString() {
return firstName + " " + lastName;
}
}
Этот подход подходит для обучения и концептуальных примеров. Однако это не лучший способ.
Во-первых, наш класс предметной области берет на себя реализацию дисплея. Таким образом, такой подход противоречит принципу единой ответственности.
Во-вторых, другие подсистемы могут использовать toString()
. Например, мы используем метод toString()
для регистрации состояния нашего объекта. Для журналов может потребоваться больше полей, чем для элемента ListView
. Таким образом, в этом случае одна реализация toString()
не может удовлетворить все потребности модуля.
2.2. Cell Factory для отображения пользовательских объектов в ListView
Давайте рассмотрим лучший способ отображения наших пользовательских объектов в JavaFX ListView
.
Каждый элемент в ListView
отображается с экземпляром класса ListCell
. ListCell
имеет свойство text
. Ячейка отображает свое текстовое
значение.
Итак, чтобы настроить текст в экземпляре ListCell
, мы должны обновить его свойство text .
Где мы можем это сделать? ListCell
имеет метод с именем updateItem
. Когда появляется ячейка для элемента, он вызывает updateItem
. Метод updateItem
также запускается при изменении ячейки. Таким образом, мы должны наследовать нашу собственную реализацию от класса ListCell
по умолчанию . В этой реализации нам нужно переопределить updateItem
.
Но как заставить ListView
использовать нашу пользовательскую реализацию вместо стандартной?
ListView
может иметь фабрику ячеек. Фабрика ячеек по умолчанию имеет значение null .
Мы должны настроить его так, чтобы ListView
отображал объекты.
Проиллюстрируем фабрику ячеек на примере:
public class PersonCellFactory implements Callback<ListView<Person>, ListCell<Person>> {
@Override
public ListCell<Person> call(ListView<Person> param) {
return new ListCell<>(){
@Override
public void updateItem(Person person, boolean empty) {
super.updateItem(person, empty);
if (empty || person == null) {
setText(null);
} else {
setText(person.getFirstName() + " " + person.getLastName());
}
}
};
}
}
CellFactory
должен реализовать обратный вызов JavaFX. Интерфейс обратного вызова
в JavaFX аналогичен стандартному интерфейсу функций
Java . Однако JavaFX использует интерфейс обратного вызова
по историческим причинам.
Мы должны вызвать реализацию метода updateItem
по умолчанию . Эта реализация запускает действия по умолчанию, такие как подключение ячейки к объекту и отображение строки для пустого списка.
Реализация метода updateItem
по умолчанию также вызывает setText
. Затем он устанавливает текст, который будет отображаться в ячейке.
2.3. Отображение пользовательских элементов в JavaFX ListView с помощью пользовательских виджетов
ListCell
предоставляет нам возможность настроить пользовательский виджет в качестве контента. Все, что нам нужно сделать для отображения объектов домена в пользовательских виджетах, — это использовать setGraphics()
вместо setCell().
Предположим, нам нужно отобразить каждую строку как CheckBox
. Давайте взглянем на соответствующую фабрику ячеек:
public class CheckboxCellFactory implements Callback<ListView<Person>, ListCell<Person>> {
@Override
public ListCell<Person> call(ListView<Person> param) {
return new ListCell<>(){
@Override
public void updateItem(Person person, boolean empty) {
super.updateItem(person, empty);
if (empty) {
setText(null);
setGraphic(null);
} else if (person != null) {
setText(null);
setGraphic(new CheckBox(person.getFirstName() + " " + person.getLastName()));
} else {
setText("null");
setGraphic(null);
}
}
};
}
}
В этом примере мы устанавливаем для свойства text значение
null
. Если существуют и текстовые
, и графические
свойства, текст будет отображаться рядом с виджетом.
Конечно, мы можем настроить логику обратного вызова CheckBox
и другие свойства на основе данных нашего пользовательского элемента. Это требует некоторого кодирования, так же, как и настройка текста виджета.
3. Заключение
В этой статье мы рассмотрели способ отображения пользовательских элементов в JavaFX ListView
. Мы видели, что ListView
позволяет достаточно гибко настроить его. Мы даже можем отображать пользовательские виджеты в наших ячейках ListView.
Как всегда, код примеров доступен на GitHub .