Serialize JavaFX components
I'm trying to develop a little drag & drop application under Java FX. User will drop JFX components like Buttons, Menus, Labels on certain positions. When done, he will save this layout and later on he will reopen the layout and he will use it again.
Its important to store the information about all objects that are dropped on some position.
I decided to use serialization for this purpose. But I'm not able to serialize JavaFX components. I tried to serialize Buttons, Scenes, Stages, JFXPane but nothing seemed to work (I obtained NotSerializableException).
Any suggestions how to save all the components and then retrieve them ?
P.S.: I was trying to find out some method with FXML but I did not succeed.
Thank you very much for your answers :)
You are correct, JavaFX (as of 2.1) does not support serialization of components using the Java Serializable interface - so you cannot use that mechanism.
JavaFX can deserialize from an FXML document using the FXMLLoader.load() method.
The trick though, is how to write your existing components and states out to FXML?
Currently, there is nothing public from the platform which performs FXML serialization. Apparently, creating a generic scenegraph => FXML serializer is quite a complex task (and there is no public 3rd party API for this that I know of). It wouldn't be too difficult to iterate over the scenegraph and write out FXML for a limited set of components and attributes.
If the main goal of saving user components on the servers side - is to have a possibility to show the same interface to the user - why not to save all descriptive information you need about users components, and when it is needed - just rebuild user interface again, using stored descriptive information? Here is primitive example:
/* That is the class for storing information, which you need from your components*/
public class DropedComponentsCoordinates implements Serializable{
private String componentID;
private String x_coord;
private String y_coord;
//and so on, whatever you need to get from yor serializable objects;
//getters and setters are assumed but not typed here.
}
/* I assume a variant with using FXML. If you don't - the main idea does not change*/
public class YourController implements Initializable {
List<DropedComponentsCoordinates> dropedComponentsCoordinates;
@Override
public void initialize(URL url, ResourceBundle rb) {
dropedComponentsCoordinates = new ArrayList();
}
//This function will be fired, every time
//a user has dropped a component on the place he/she wants
public void OnDropFired(ActionEvent event) {
try {
//getting the info we need from components
String componentID = getComponentID(event);
String component_xCoord = getComponent_xCoord(event);
String component_yCoord = getComponent_yCoord(event);
//putting this info to the list
DropedComponentsCoordinates dcc = new DropedComponentsCoordinates();
dcc.setX_Coord(component_xCoord);
dcc.setY_Coord(component_yCoord);
dcc.setComponentID(componentID);
} catch (Exception e) {
e.printStackTrace();
}
}
private String getComponentID(ActionEvent event){
String componentID;
/*getting cpmponentID*/
return componentID;
}
private String getComponent_xCoord(ActionEvent event){
String component_xCoord;
/*getting component_xCoord*/
return component_xCoord;
}
private String getComponent_yCoord(ActionEvent event){
String component_yCoord;
/*getting component_yCoord*/
return component_yCoord;
}
}