如何为我的项目实现Serializable具有持久性?

时间:2017-06-30 07:47:59

标签: 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"));

    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);
    });

}

然后是EventsBean:

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 ...

我想序列化表格中的数据。我认为可序列化对象是来自ObservableList的dataList。我的问题是在哪里实现Serializable接口?在我的情况下,这是持久性的最佳解决方案吗?

提前谢谢!

1 个答案:

答案 0 :(得分:0)

您应首先问问自己是否真的想在此处使用对象序列化。使用不同的持久性方法可能更好:例如使用JSON编组库,例如GSON。大多数此类库只使用对象的 addi $s1,$0,0 # i = 0 addi $t1,$0,1 # j = 1 while: addi $s1,$s1,-2 #i = i -2 beq $s1,$t1,done #Branch to done If i = 1 (the opposite) j while # jump to while for loop through again done: get方法来查找数据,因此可能适用于您的set类,只需要很少的额外代码。

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

首先,创建JavaFX属性Serializable,因此默认的序列化机制不会尝试序列化它们,然后定义自定义transientreadObject方法来定义对象应该如何序列:

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()); } } 实现通常不可序列化,因此您需要序列化“常规”列表以序列化数据,即:

ObservableList

并回读:

ObjectOutputStream s = ... ;
s.writeObject(new ArrayList<EventsBean>(dataList));