Serialize hashmap with non-serializable objects


Question

How do i serialize a hashmap containing non-serializable objects, in my case JavaFX Components?

final HashMap<String, Button> mapButton = new HashMap<>();
// some for loop adding the components..
try {
     FileOutputStream fileOut = new FileOutputStream("Resources/");
     ObjectOutputStream objStream = new ObjectOutputStream(fileOut);
     objStream.writeObject(mapButton);
     objStream.close();
     fileOut.close();
     System.out.println("Serialized HashMap mapButtons has been stored"
                         + " in /tmp/store");
    } catch (IOException i) {
          i.printStackTrace();
    }

Throws:

java.io.NotSerializableException: javafx.scene.control.Button

1
1
1/21/2014 10:40:06 AM

Accepted Answer

If you want to serialize objects than they must be Serializable.

Since a javafx.scene.control.Button is not serializable you must find another way to save the button's state somewhere else. E.g. by introducing a memento class that safes the state:

public class ButtonMemento implements Serializable {

       private static final long serialVersionUID = 1L;

       private boolean text;

       /*
        * Creates a memento that safes the given button's current state.
        */
       public ButtonMemento(Button button){
             this.text = button.getText();
            // extend to record more properties of the button
       }

       /*
        * Used to apply the current mementos state to a button
        */
       public void applyState(Button button){
           button.setText(text);
           // extend to apply more properties to the button
       }
}

The ButtonMemento class is a way to safe the state of an object that is not serializable and restore it later.

final HashMap<String, ButtonMemento> mapButton = new HashMap<>();

for(Button b : buttons){
    String mapKey = ...;
    mapButton.put(mapKey, new ButtonMemento(b));
}    

try {
    FileOutputStream fileOut = new FileOutputStream("Resources/");
    ObjectOutputStream objStream = new ObjectOutputStream(fileOut);
    objStream.writeObject(mapButton);
    objStream.close();
    fileOut.close();
    System.out.println("Serialized HashMap mapButtons has been stored"
                     + " in /tmp/store");
} catch (IOException i) {
      i.printStackTrace();
}

Maybe you can implement somthing like a BeanMemento that can store the properties of a bean that are serializable and therefore can be used with every object that fulfills the java bean specification.

2
1/21/2014 11:07:50 AM

You can create a serializable wrapper around Button and implement custom serialization in it. You will be saving buttons properties in writeObject, read them back and recreated Buttons in readObject


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon