我试图基于从JSON文件检索到的一些数据在javafx中创建表视图,但是我很难显示它们。
那是我得到的错误消息:
com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Collection type [collection type; class javafx.collections.ObservableList, contains [simple type, class app.model.Savefile]]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:266)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:241)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:394)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3169)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3062)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2122)
at app.model.SavefileJSON.getAllSavefiles(SavefileJSON.java:31)
at app.controller.Controller.initialize(Controller.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
at app.Main.start(Main.java:19)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$161(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Collection type [collection type; class javafx.collections.ObservableList, contains [simple type, class app.model.Savefile]]
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:841)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:390)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:348)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:261)
... 35 more
com.fasterxml.jackson.databind.JsonMappingException: Can not find a deserializer for non-concrete Collection type [collection type; class javafx.collections.ObservableList, contains [simple type, class app.model.Savefile]]
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:266)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:241)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:394)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:3169)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3062)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2122)
at app.model.SavefileJSON.getAllSavefiles(SavefileJSON.java:31)
at app.Main.main(Main.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.IllegalArgumentException: Can not find a deserializer for non-concrete Collection type [collection type; class javafx.collections.ObservableList, contains [simple type, class app.model.Savefile]]
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.createCollectionDeserializer(BasicDeserializerFactory.java:841)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:390)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:348)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:261)
... 19 more
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.NullPointerException
at app.Main.main(Main.java:40)
... 11 more
Exception running application app.Main
保存文件模型:
package app.model;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Savefile {
private StringProperty name;
private StringProperty date;
@Override
public String toString() {
return "Savefile{" +
"date=" + date +
", name=" + name +
'}';
}
public Savefile(StringProperty date, StringProperty name) {
this.date = new SimpleStringProperty();
this.name = new SimpleStringProperty();
}
public Savefile() {
this.date = new SimpleStringProperty();
this.name = new SimpleStringProperty();
}
public String getDate() {
return date.get();
}
public StringProperty dateProperty() {
return date;
}
public void setDate(String date) {
this.date.set(date);
}
public String getName() {
return name.get();
}
public StringProperty nameProperty() {
return name;
}
public void setName(String name) {
this.name.set(name);
}
}
SavefileJSON:
public static ObservableList<Savefile> getAllSavefiles(){
ObjectMapper mapper = new ObjectMapper();
File file = new File(JSONFILEPATH);
try {
ObservableList<Savefile> serverfiles = mapper.readValue(file, new TypeReference<ObservableList<Savefile>>(){});
return serverfiles;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
和控制器:
package app.controller;
import app.model.PropertiesFile;
import app.model.Savefile;
import app.model.SavefileJSON;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import jdk.jfr.events.ExceptionThrownEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Controller {
public final static String CURRENT_PATH = System.getProperty("user.dir");
public final static String SAVES_PATH = CURRENT_PATH + "\\saves";
@FXML
private TableView<Savefile> savesTableView;
@FXML
private TableColumn<Savefile, String> nameColumn;
@FXML
private TableColumn<Savefile, String> dataColumn;
@FXML
private Button saveButton;
@FXML
private Button loadButton;
@FXML
private Button deleteButton;
@FXML
private TextField saveFileNameText;
private static void copyFile(Path sourceDirectory, Path targetDirectory) throws IOException {
//copy source to target using Files Class
Files.copy(sourceDirectory, targetDirectory);
}
@FXML
private void initialize(){
// TableColumn<Savefile,String> nameColumn = new TableColumn<Savefile,String>("First Name");
// nameColumn.setCellValueFactory(new PropertyValueFactory<Savefile,String>("name"));
nameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
dataColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
ObservableList<Savefile> saveFiles = SavefileJSON.getAllSavefiles();
populateServerfiles(saveFiles);
}
@FXML
private void populateAndShowUser(Savefile sf){
if (sf != null){
populateSavefile(sf);
}
}
@FXML
private void populateSavefile (Savefile sf){
ObservableList<Savefile> userData = FXCollections.observableArrayList();
userData.add(sf);
savesTableView.setItems(userData);
}
@FXML
private void populateServerfiles(ObservableList<Savefile> savefilesData){
savesTableView.setItems(savefilesData);
}
@FXML
public void createSaveFile(ActionEvent event) {
if (saveFileNameText.getText().equals("") || saveFileNameText.getText()==null){
saveFileNameText.setStyle("-fx-border-color: #ff0000;" +
"-fx-border-radius: 5");
saveFileNameText.setPromptText("Name field required");
}else{
String location = SAVES_PATH + "\\" + saveFileNameText.getText();
File newSaveFileDirectory = new File(location);
boolean result = false;
//CREATING THE DIR
try{
newSaveFileDirectory.mkdir();
SavefileJSON sfJ = new SavefileJSON();
DateFormat dateFormat = new SimpleDateFormat("dd/MM HH:mm");
Date date = new Date();
Savefile sf = new Savefile();
sf.setName(saveFileNameText.getText().toString());
sf.setDate(dateFormat.format(date).toString());
sfJ.addSavefile(sf);
//COPY THE ACTUAL SAVE FILE TO THE DIR
PropertiesFile pf = new PropertiesFile();
try{
copyFile(Paths.get(pf.getProp("sekiroLocation")), Paths.get(SAVES_PATH + "\\" +(saveFileNameText.getText())+ "\\S0000.sl2"));
}catch(IOException e){
System.out.println(e);
System.out.println("Copy sf failed");
}
//check if the name its unique
result = true;
}catch(SecurityException se){
System.out.println(se);
}
if (result){
System.out.println("Save file directory created");
}
}
}
}
有人可以帮我实现它吗?最初,我一直使用savefilejson中的 List 而不是 ObservableList ,并且我可以成功地从json文件中检索所有条目,但是由于我将其更改为ObservableList以便显示结果一切都坏了,我不知道如何解决
答案 0 :(得分:1)
我认为您的问题是Jackson不能直接生成ObservableList(因为自然地,它没有JavaFX专用ObservableList的反序列化器)。
但是在getAllSavefiles
中,您可以轻松地从JSON文件创建常规列表,然后从列表中的项目创建ObservableList。
您可以为此使用FXCollections.observableList(List<E> list)
。
就像这样(从我的头顶来看,未经测试的代码):
public static ObservableList<Savefile> getAllSavefiles(){
ObjectMapper mapper = new ObjectMapper();
File file = new File(JSONFILEPATH);
try {
List<Savefile> serverfiles = mapper.readValue(file, new TypeReference<ArrayList<Savefile>>(){});
return FXCollections.observableList(serverfiles);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}