Java 如何实现可序列化以使我的项目具有持久性?

Java 如何实现可序列化以使我的项目具有持久性?,java,serialization,javafx,serializable,observablelist,Java,Serialization,Javafx,Serializable,Observablelist,我的主要方法是: public class ToDoList extends Application{ public static void main(String[] args) { launch(args); } public void start(Stage primaryStage) throws Exception { Pane pane = FXMLLoader.load(getClass().getResource("ToDoList.fxml"));

我的主要方法是:

public class ToDoList extends Application{

public static void main(String[] args) {
    launch(args);
}

public void start(Stage primaryStage) throws Exception {

    Pane pane = FXMLLoader.load(getClass().getResource("ToDoList.fxml"));

    Scene scene = new Scene(pane);
    scene.getStylesheets().add(getClass().getResource("ToDoListStyle.css").toExternalForm());
    primaryStage.setScene(scene);
    primaryStage.setTitle("Plan yourself");
    primaryStage.show();
}
}

然后控制器的一部分:

    ObservableList<EventsBean> dataList = FXCollections.observableArrayList();

@Override
public void initialize(URL location, ResourceBundle resources) {
    System.out.println("The pane loaded");

    List<String> myList;
    try {
        myList = Files.lines(Paths.get("src/com/todolist/EventsList.txt")).collect(Collectors.toList());
        eventsSelector.setItems(FXCollections.observableArrayList(myList));
    } catch (IOException e) {
        System.out.println("Don t find file");
    }

    removeCol.setCellFactory(CheckBoxTableCell.forTableColumn(removeCol));
    eventCol.setCellValueFactory(new PropertyValueFactory<EventsBean, String>("event"));
    dateCol.setCellValueFactory(new PropertyValueFactory<EventsBean, LocalDate>("date"));
    doneCol.setCellValueFactory(new PropertyValueFactory<EventsBean, String>("done"));
    doneCol.setCellFactory(TextFieldTableCell.<EventsBean>forTableColumn());
    doneCol.setOnEditCommit((CellEditEvent<EventsBean, String> t) -> {
        ((EventsBean) t.getTableView().getItems().get(t.getTablePosition().getRow()))
                .setDone(t.getNewValue());
    });
    observationCol.setCellValueFactory(new PropertyValueFactory<EventsBean, String>("observation"));
    removeCol.setCellValueFactory(cellData -> cellData.getValue().selectedProperty());
    observationCol.setCellFactory(TextFieldTableCell.<EventsBean>forTableColumn());
    observationCol.setOnEditCommit((CellEditEvent<EventsBean, String> t) -> {
        ((EventsBean) t.getTableView().getItems().get(t.getTablePosition().getRow()))
                .setObservation(t.getNewValue());
    });
    observationCol.setSortable(false);

    eventsTable.setItems(dataList);
    eventsTable.setEditable(true);

    bttnAddEvent.setOnAction((ActionEvent e) -> {
        try {
            text = eventsSelector.getValue().toString();
            dataList.add(new EventsBean(text, isoDate, "",  "", false));
        } catch (Exception e1) {
            System.out.println("Nothing selected");
        }
    });

    bttnRemove.setOnAction((ActionEvent e) -> {
        ObservableList<EventsBean> dataListToRemove = FXCollections.observableArrayList();
        for (EventsBean bean : dataList) {
            if (bean.getSelected()) {
                dataListToRemove.add(bean);
            }
        }
        dataList.removeAll(dataListToRemove);

        // Below code it is for delete a focused row
        // EventsBean selectedItem = eventsTable.getSelectionModel().getSelectedItem();
        // eventsTable.getItems().remove(selectedItem);
    });

}
observeListDataList=FXCollections.observearraylist();
@凌驾
公共void初始化(URL位置、ResourceBundle资源){
System.out.println(“加载的窗格”);
列出我的清单;
试一试{
myList=Files.lines(path.get(“src/com/todolist/EventsList.txt”)).collect(Collectors.toList());
eventsSelector.setItems(FXCollections.observableArrayList(myList));
}捕获(IOE异常){
System.out.println(“找不到文件”);
}
setCellFactory(CheckBoxTableCell.forTableColumn(removeCol));
eventCol.setCellValueFactory(新属性ValueFactory(“事件”);
dateCol.setCellValueFactory(新属性ValueFactory(“日期”);
doneCol.setCellValueFactory(新的PropertyValueFactory(“完成”);
doneCol.setCellFactory(TextFieldTableCell.forTableColumn());
doneCol.setOnEditCommit((CellEditEvent t)->{
((EventsBean)t.getTableView().getItems().get(t.getTablePosition().getRow()))
.setDone(t.getNewValue());
});
observationCol.setCellValueFactory(新属性ValueFactory(“观察”));
removeCol.setCellValueFactory(cellData->cellData.getValue().selectedProperty());
observationCol.setCellFactory(TextFieldTableCell.forTableColumn());
observationCol.setOnEditCommit((CellEditEvent t)->{
((EventsBean)t.getTableView().getItems().get(t.getTablePosition().getRow()))
.setObservation(t.getNewValue());
});
observationCol.setSortable(假);
eventsTable.setItems(数据列表);
eventsTable.setEditable(true);
bttnAddEvent.setOnAction((ActionEvent e)->{
试一试{
text=eventsSelector.getValue().toString();
add(neweventsbean(text,isoDate,“,”,false));
}捕获(异常e1){
System.out.println(“未选择任何内容”);
}
});
bttnRemove.setOnAction((ActionEvent e)->{
ObservableList dataListToRemove=FXCollections.observableArrayList();
for(EventsBean:dataList){
if(bean.getSelected()){
添加(bean);
}
}
dataList.removeAll(dataListToRemove);
//下面的代码用于删除重点行
//EventsBean selectedItem=eventsTable.getSelectionModel().getSelectedItem();
//eventsTable.getItems().remove(selectedItem);
});
}
然后事件bean:

public class EventsBean {


private SimpleStringProperty event;
private SimpleObjectProperty<LocalDate> date;
private SimpleStringProperty done;
private SimpleStringProperty observation;
private SimpleBooleanProperty selected;

public EventsBean(String event, LocalDate date, String done, String observation, boolean selected) {
    this.event = new SimpleStringProperty(event);
    this.date = new SimpleObjectProperty<LocalDate>(date);
    this.done = new SimpleStringProperty(done);
    this.observation = new SimpleStringProperty(observation);
    this.selected = new SimpleBooleanProperty(selected);
}
// Getters and Setters ...
公共类事件bean{
私人物业活动;
私有SimpleObject属性日期;
私有财产;
私人财产观察;
选择私有SimpleBoleAnProperty;
公共事件bean(字符串事件、LocalDate日期、字符串完成、字符串观察、布尔选择){
this.event=新的SimpleStringProperty(事件);
this.date=新的SimpleObject属性(日期);
this.done=新的SimpleStringProperty(done);
this.observation=新的SimpleStringProperty(观察);
this.selected=新的SimpleBoleAnProperty(已选择);
}
//接球手和接球手。。。
我想序列化表中的数据。我认为可序列化的对象是ObservableList中的dataList。我的问题是在哪里实现可序列化接口?这是我的持久性最好的解决方案


提前谢谢!

您应该首先问问自己是否真的想在这里使用对象序列化。最好使用不同的持久性方法:例如,使用JSON封送库,例如。大多数这样的库只使用对象的
get
set
方法来查找数据,因此可能需要使用您的
EventsBean
类只需要很少的额外代码

如果您确实想使用Java对象序列化,则需要使
EventsBean
Serializable
。通常这很简单,但您将遇到的问题是JavaFX属性类不实现
Serializable
,因此天真地使
EventsBean
实现
Serializable
并尝试序列化它的实例将生成运行时异常。您需要使用自定义序列化来执行此操作

首先,使JavaFX属性成为瞬态的,这样默认的序列化机制就不会尝试对它们进行序列化,然后定义自定义的
readObject
writeObject
方法来定义对象的序列化方式:

public class EventsBean implements Serializable {


    private transient SimpleStringProperty event;
    private transient SimpleObjectProperty<LocalDate> date;
    private transient SimpleStringProperty done;
    private transient SimpleStringProperty observation;
    private transient SimpleBooleanProperty selected;

    // constructors...

    // example get/set/property methods:
    public StringProperty eventProperty() {
        return event ;
    }

    public final String getEvent() {
        return eventProperty().get();
    }

    public final void setEvent(String event) {
        eventProperty().set(event);
    }

    // etc. for other properties...


    // custom serialization:
    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeObject(getEvent()); // write event as a plain String
        s.writeObject(getDate()); 
        s.writeObject(getDone());
        s.writeObject(getObservation());
        s.writeBoolean(isSelected());
    }

    // custom deserialization:
    private void readObject(ObjectInputStream s) throws IOException {
        s.defaultReadObject();
        this.event = new SimpleStringProperty((String)s.readObject());
        this.data = new SimpleObjectProperty<>((LocalDate)s.readObject());
        this.done = new SimpleStringProperty((String)s.readObject());
        this.observation = new SimpleStringProperty((String)s.readObject());
        this.selected = new SimpleBooleanProperty(s.readBoolean());
    }
}
要重新阅读:

ObjectInputStream s = ... ;
dataList.setAll((List<EventsBean>)s.readObject());
objectInputStreams=;
setAll((List)s.readObject());

序列化的类必须是可序列化的类。在这种情况下,
observateList
EventsBean
。这是非常基本的。@EJP但请注意JavaFX属性类(
SimpleStringProperty
等)不要实现
Serializable
,这会让它变得有点棘手。@James_D同意,但我不知道你为什么对我这么说。好的,我尝试了上述解决方案,但我在反序列化方面遇到了问题。然后我想使用GSON库,但它也是序列化的,在反序列化时我出现了错误:
ObjectInputStream s = ... ;
dataList.setAll((List<EventsBean>)s.readObject());