代码之家  ›  专栏  ›  技术社区  ›  Daniel

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

  •  -1
  • Daniel  · 技术社区  · 7 年前

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

    然后事件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 ...
    

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

    1 回复  |  直到 7 年前
        1
  •  0
  •   James_D    7 年前

    您应该首先问问自己是否真的想在这里使用对象序列化。最好使用不同的持久性方法:例如,使用JSON封送库,例如 GSON 。大多数这样的库只使用对象的 get set EventsBean 使用很少的额外代码初始化。

    事件bean Serializable 。通常这很简单,但您将遇到的问题是JavaFX属性类没有实现 真是太天真了 使生效 尝试序列化它的实例将生成运行时异常。要做到这一点,需要使用自定义序列化。

    首先,创建JavaFX属性 transient 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());
        }
    }
    

    ObservableList 实现通常不可序列化,因此需要序列化“常规”列表以序列化数据,即:

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

    回过头来看:

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