我已经在JavaFX中为ListView实现了自定义ListCell,类似于以下教程:https://www.turais.de/how-to-custom-listview-cell-in-javafx/
我的ListCell包含3个元素,ImageView和2个带有一些描述的标签,这些描述是从数据库中加载的。因为我坚持使用MVC模式,所以ListUI fxml包含在mainUI fxml文件中。
运行程序并向下滚动列表视图时,出现以下错误消息:
javafx.fxml.LoadException: Root value already specified.
/D:/Semester%207/iExplore/iExplore/out/production/iExplore/listComponent/listcell.fxml
/D:/Semester%207/iExplore/iExplore/out/production/iExplore/listComponent/listcell.fxml
/D:/Semester%207/iExplore/iExplore/out/production/iExplore/listComponent/listcell.fxml
at javafx.fxml/javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
at javafx.fxml/javafx.fxml.FXMLLoader.createElement(FXMLLoader.java:2770)
at javafx.fxml/javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2719)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
at listComponent.CustomListViewCell.updateItem(CustomListViewCell.java:50)
ListView Controller
import authentification.UserConnectionSingleton;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ListView;
import models.Events;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
public class ListController implements Initializable {
@FXML
private ListView<Events> EventList;
private ObservableList<Events> eventsobservableList;
private UserConnectionSingleton con;
private EntityManager entityManager;
private List<Events> tempList;
public ListController(){
try{
con = UserConnectionSingleton.getInstance();
entityManager = con.getManager();
TypedQuery<Events> tq1 = entityManager.createNamedQuery("Events.findAllEvents",Events.class);
tempList = tq1.getResultList();
System.out.println(tempList.size());
eventsobservableList = FXCollections.observableArrayList();
eventsobservableList.addAll(tempList);
} catch(Exception e){
Alert alert = new Alert(Alert.AlertType.WARNING,"Check the internet connection...");
alert.showAndWait();
e.printStackTrace();
}
}
@Override
public void initialize(URL location,ResourceBundle resources) {
EventList.setItems(eventsobservableList);
EventList.setCellFactory(customListViewCell -> new CustomListViewCell());
}
}
CustomCell Controller
import authentification.UserConnectionSingleton;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import models.Events;
import models.Location;
import models.Pictures;
import javax.persistence.EntityManager;
public class CustomListViewCell extends ListCell<Events> {
@FXML
private ImageView cellLogo;
@FXML
private Label descriptionLabel,locationLabel;
@FXML
private HBox boxLayout;
private FXMLLoader loader;
private Image image;
private String imageURL;
private int id;
private UserConnectionSingleton con;
private EntityManager entityManager;
private String city;
@Override
protected void updateItem(Events event,boolean empty) {
super.updateItem(event,empty);
if(empty || event == null){
setText(null);
setGraphic(null);
} else {
if(loader == null){
loader = new FXMLLoader(getclass().getResource("/listComponent/listcell.fxml"));
loader.setController(this);
}
try{
loader.load();
con = UserConnectionSingleton.getInstance();
entityManager = con.getManager();
} catch(Exception e){
Alert alert = new Alert(Alert.AlertType.WARNING,"Check the internet connection...");
alert.showAndWait();
e.printStackTrace();
}
id = event.getId();
imageURL = entityManager.find(Pictures.class,id).getLogo();
city = entityManager.find(Location.class,id).getcity();
System.out.println(imageURL);
image = new Image(imageURL);
cellLogo = new ImageView(image);
descriptionLabel.setText(event.getShortDescription());
locationLabel.setText(city);
setText(null);
setGraphic(boxLayout);
}
}
}
ListView Fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.effect.ColorAdjust?>
<?import javafx.scene.layout.VBox?>
<VBox fx:id="listLayout" alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="328.0" prefWidth="543.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1" fx:controller="listComponent.ListController">
<effect>
<ColorAdjust />
</effect>
<children>
<ListView fx:id="EventList" prefHeight="365.0" prefWidth="821.0" />
</children>
</VBox>
自定义ListCell FXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<HBox fx:id="boxLayout" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="177.0" prefWidth="534.0" xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
<children>
<ImageView fx:id="cellLogo" fitHeight="166.0" fitWidth="165.0" pickOnBounds="true" preserveRatio="true" />
<VBox alignment="CENTER" prefHeight="160.0" prefWidth="259.0">
<children>
<Label fx:id="descriptionLabel" text="Label" />
</children>
</VBox>
<VBox alignment="BOTTOM_RIGHT" prefHeight="165.0" prefWidth="127.0">
<children>
<Label fx:id="locationLabel" text="Label" />
</children>
</VBox>
</children>
<padding>
<Insets bottom="10.0" left="5.0" top="10.0" />
</padding>
</HBox>