我正在尝试使用 fxml 填充 ListView ,但在运行我的程序时,我的 ListView
无法调用方法 setCellFactory
。
有人可以帮助我并解释如何修复我的代码吗?
listviewContoller.java -->
public class ListViewController implements Initializable {
@SuppressWarnings("rawtypes")
@FXML
private ListView listView;
private ArrayList<String> arrayList = new ArrayList<>();
@SuppressWarnings("rawtypes")
ObservableList observableList = FXCollections.observableArrayList();
@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
arrayList.add("String 1");
arrayList.add("String 2");
arrayList.add("String 3");
arrayList.add("String 4");
observableList.setAll(arrayList);
listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
@Override
public ListCell<String> call(ListView<String> param) {
return new ListViewCell();
}
});
}
}
ListViewCell.java -->
public class ListViewCell extends ListCell<String> {
@Override
public void updateItem(String string, boolean empty) {
super.updateItem(string, empty);
if(string != null) {
Data data = new Data();
data.setInfo(string);
setGraphic(data.getBox());
} else {
Data data = new Data();
data.setInfo("AAAA");
setGraphic(data.getBox());
}
}
}
Data.java -->
public class Data implements Initializable{
@FXML
private HBox hBox;
@FXML
private ImageView imageListCell;
@FXML
private Label labelListCell;
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/Tracker/UI/listCellItem.fxml"));
try {
loader.load();
} catch (IOException e){
throw new RuntimeException(e);
}
}
public void setInfo(String string) {
labelListCell.setText(string);
}
public HBox getBox() {
return hBox;
}
}
最佳答案
setCellFactory
被调用,但您使用的单元格不以任何方式显示内容:
创建 Data
的实例不会加载 fxml 并且没有加载 fxml,getBox()
总是返回null
.
顺便说一句:重复使用Data
是个好主意。以避免重新加载 fxml。
通常在这种情况下,您会创建一个自定义 Node
输入从 fxml 加载的内容:
public class Data extends HBox {
public Data() {
// load fxml here
FXMLLoader loader = new FXMLLoader(getClass().getResource("/Tracker/UI/listCellItem.fxml"));
loader.setController(this);
loader.setRoot(this);
try {
loader.load();
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
@FXML
private ImageView imageListCell;
@FXML
private Label labelListCell;
public void setInfo(String string) {
labelListCell.setText(string);
}
}
listCellItem.fxml
<!-- no fx:controller attribute allowed here -->
<fx:root type="javafx.scene.layout.HBox" xmlns:fx="http://javafx.com/fxml/1">
<!-- contents of the root tag of the old fxml should be copied here -->
</fx:root>
请注意,您还应该复制旧 fxml 根元素的所有属性,但对于 fx:controller
属性。
public class ListViewCell extends ListCell<String> {
private final Data data;
public ListViewCell() {
this.data = new Data();
setGraphic(this.data);
}
@Override
public void updateItem(String string, boolean empty) {
super.updateItem(string, empty);
data.setInfo(string == null ? "AAAA" : string);
}
}
此外,您从未设置 items
的新值属性:
@Override
public void initialize(URL location, ResourceBundle resources) {
arrayList.add("String 1");
arrayList.add("String 2");
arrayList.add("String 3");
arrayList.add("String 4");
observableList.setAll(arrayList);
listView.setItems(observableList);
...
}
此外,不要使用 @SuppressWarnings("rawtypes")
和@SuppressWarnings("unchecked")
,为什么不简单地添加 <String>
作为类型参数???
关于JavaFX - ListView 不填充 fxml 中的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41567871/