坚持使用 JavaFX ListView
Stuck with JavaFX ListView
我正在尝试将基于 Android 的应用重写为 JavaFX,但遇到一个问题。
问题的简要说明如下:
1) 我有 类 的层次结构,根 abstract class Field
和子级 类 的数量,例如 FieldCat
、FieldZebra
、FieldDog
等等 - 这些 类 中的每一个都有自己足够独特的结构和可视化表示(以 FXML 的形式)
2) ListView
应显示属于 Field
层次结构的对象列表 - 存储在 ObservableList<Field> listItems
中
3) 现在我需要将每个 FieldWhatever
对象膨胀为 ListView
中的单独行
声明
我无法使用 JavaFX ListView
控制(?!)
证明
创建 ListView
元素的唯一方法是提供 CellFactory
:
public class FieldsListCellFactory<T extends Field> implements Callback<ListView<T>, ListCell<T>> {
@Override
public ListCell<T> call(ListView<T> listView) {
//blah-blah
}
}
Factory 本身接收单个参数 ListView
,因此它可以为 ListView
的所有元素生成相同的 ListCell
- 换句话说,我不能填充不同的 UI 元素取决于基础 FieldWhatever
对象。
一开始我什至不敢相信-这怎么可能?在 Android 中,我可以根据对象 type/hierarchy 等增加任何类型的复杂性 UI,但在 JavaFX 中 - 不可能吗?相信我 - 我花了几个小时试图修复它 - 没用。
问题
- 我是对的吗(我很高兴听到我错了)
- 做什么?如何解决情况和 put/place/inflate in
List/Table 列表完全不同 objects/classes/entities?
广告 1 你错了。
广告 2 代码如下:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class ListViewApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
ListView<Animal> listview = new ListView<>(FXCollections.observableArrayList(new Dog(1, "John"), new Cat(2, "Fluffy")));
listview.setCellFactory(param -> new ListCell<Animal>() {
@Override
protected void updateItem(Animal animal, boolean empty) {
super.updateItem(animal, empty);
if (animal != null) {
setText(animal.getText());
}
}
});
stage.setScene(new Scene(listview));
stage.show();
}
}
class Animal {
protected final int id;
public Animal(int id) {
this.id = id;
}
protected String getText() {
return "";
}
}
class Dog extends Animal {
private final String owner;
public Dog(int id, String owner) {
super(id);
this.owner = owner;
}
@Override
protected String getText() {
return "DOG id=" + id + ", owner=" + owner;
}
}
class Cat extends Animal {
private final String name;
public Cat(int id, String name) {
super(id);
this.name = name;
}
@Override
protected String getText() {
return "CAT id=" + id + ", name=" + name;
}
}
我正在尝试将基于 Android 的应用重写为 JavaFX,但遇到一个问题。
问题的简要说明如下:
1) 我有 类 的层次结构,根 abstract class Field
和子级 类 的数量,例如 FieldCat
、FieldZebra
、FieldDog
等等 - 这些 类 中的每一个都有自己足够独特的结构和可视化表示(以 FXML 的形式)
2) ListView
应显示属于 Field
层次结构的对象列表 - 存储在 ObservableList<Field> listItems
3) 现在我需要将每个 FieldWhatever
对象膨胀为 ListView
声明
我无法使用 JavaFX ListView
控制(?!)
证明
创建 ListView
元素的唯一方法是提供 CellFactory
:
public class FieldsListCellFactory<T extends Field> implements Callback<ListView<T>, ListCell<T>> {
@Override
public ListCell<T> call(ListView<T> listView) {
//blah-blah
}
}
Factory 本身接收单个参数 ListView
,因此它可以为 ListView
的所有元素生成相同的 ListCell
- 换句话说,我不能填充不同的 UI 元素取决于基础 FieldWhatever
对象。
一开始我什至不敢相信-这怎么可能?在 Android 中,我可以根据对象 type/hierarchy 等增加任何类型的复杂性 UI,但在 JavaFX 中 - 不可能吗?相信我 - 我花了几个小时试图修复它 - 没用。
问题
- 我是对的吗(我很高兴听到我错了)
- 做什么?如何解决情况和 put/place/inflate in List/Table 列表完全不同 objects/classes/entities?
广告 1 你错了。
广告 2 代码如下:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
public class ListViewApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
ListView<Animal> listview = new ListView<>(FXCollections.observableArrayList(new Dog(1, "John"), new Cat(2, "Fluffy")));
listview.setCellFactory(param -> new ListCell<Animal>() {
@Override
protected void updateItem(Animal animal, boolean empty) {
super.updateItem(animal, empty);
if (animal != null) {
setText(animal.getText());
}
}
});
stage.setScene(new Scene(listview));
stage.show();
}
}
class Animal {
protected final int id;
public Animal(int id) {
this.id = id;
}
protected String getText() {
return "";
}
}
class Dog extends Animal {
private final String owner;
public Dog(int id, String owner) {
super(id);
this.owner = owner;
}
@Override
protected String getText() {
return "DOG id=" + id + ", owner=" + owner;
}
}
class Cat extends Animal {
private final String name;
public Cat(int id, String name) {
super(id);
this.name = name;
}
@Override
protected String getText() {
return "CAT id=" + id + ", name=" + name;
}
}