2017-06-30 1 views
-1

私の主な方法:プロジェクトに永続性を持たせるためにシリアライザブルを実装する方法は?

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

あなたがシリアライズする必要があるクラスは、シリアル化する必要があります。この場合、 'ObservableList'と' EventsBean'です。これはむしろ基本的なものです。 – EJP

+0

@EJPしかし、JavaFXプロパティークラス( 'SimpleStringProperty'など)は' Serializable'を実装していないので、少し面倒です。 –

+0

@James_D合意しましたが、私がなぜそれを私にアドバイスしているのか分かりません。 – EJP

答えて

0

ここでオブジェクトのシリアライゼーションを本当に使用するかどうかを最初に確認する必要があります。異なる永続性アプローチを使用する方がよい場合があります。 GSONなどのJSONマーシャリングライブラリを使用します。ほとんどのそのようなライブラリは、オブジェクトのgetsetメソッドを使用してデータを検索するだけなので、追加のコードをほとんど入れずにEventsBeanクラスで動作する可能性があります。

Javaオブジェクトのシリアル化を使用する場合は、EventsBeanクラスSerializableにする必要があります。通常これは簡単ですが、JavaFX PropertiesクラスではSerializableが実装されていないため、EventsBeanSerializableに実装し、インスタンスをシリアル化しようとすると実行時例外が生成されます。これを行うには、カスタムシリアル化を使用する必要があります。

まず、作るのJavaFXプロパティtransient、デフォルトの直列化メカニズムは、それらをシリアル化しようとすると、その後、オブジェクトをシリアル化する方法を定義するカスタムreadObjectwriteObjectメソッドが定義されていないので、最後に

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()); 
+0

私は上記の解決策を試しましたが、デシリアライズに問題があります。それから私はGSONライブラリを使うことを考えましたが、それもシリアル化しています。逆シリアル化時にはエラーがあります: – Daniel

関連する問題