Load a Custom class


I try to save & load a custom class like on this explanation : http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:save_and_load#custom_savable_class
I also looked a lot on this forum but I didn’t find the good answer.

It’s working for save (check with dubug mode on Intellij) I can also see userData string field on my binary file .j3o.

  private static FirstModel firstModel = new FirstModel();
    /* ...
    some code (init function)
        Box cube1Mesh = new Box(1f, 1f, 1f);
        Geometry cube1Geo = new Geometry("My Textured Box", cube1Mesh);
        cube1Geo.setLocalTranslation(new Vector3f(-3f, 1.1f, 0f));
        Material cube1Mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        cube1Mat.setColor("Color", ColorRGBA.Blue);
        cube1Geo.setUserData("le caca C super bon", firstModel);
    /* ...
    some code (other function)
        String userHome = System.getProperty("user.home");
        BinaryExporter exporter = BinaryExporter.getInstance();
        File file = new File(userHome+"/Models/MyModel1.j3o");
        try {
            exporter.save(jmeApp.getRootNode(), file);
        } catch (IOException ex) {

But not for loading. I can see the key on my Spatial (Geometry) userData but value is null.

public class HelloWorld extends SimpleApplication {

    private static FirstModel firstModel;

    public static void main(String[] args) {
        HelloWorld app = new HelloWorld();

    public Geometry player;
    Boolean isRunning=true;
    public void simpleInitApp() {
        BinaryImporter imp=BinaryImporter.getInstance();
        String userHome = System.getProperty("user.home");
        BinaryImporter importer = BinaryImporter.getInstance();
        File file = new File(userHome + "/Models/" + "MyModel1.j3o");
        try {
            Node sceneNode = (Node)importer.load(file);
            sceneNode.setName("My restored node");
            firstModel = ((Geometry)((Node) rootNode.getChildren().get(0)).getChildren().get(0)).getUserData("le caca C super bon");
        } catch (IOException ex) {

Note : It’s not the same application of JME (because project is an editor/launcher (save/load))

And this is the code of the CustomClass (same for editor & launcher) :

public class FirstModel implements Savable {

    private int      someIntValue;   // some custom user data
    private float    someFloatValue; // some custom user data
    private String   someString;
    //private Material someJmeObject;  // some custom user data

    public FirstModel() {

    public void write(JmeExporter ex) throws IOException {
        OutputCapsule capsule = ex.getCapsule(this);
        capsule.write(someIntValue,   "someIntValue",   1);
        capsule.write(someFloatValue, "someFloatValue", 1f);
        capsule.write(someString, "someString", null);
        //capsule.write(someJmeObject,  "someJmeObject",  new Material());

    public void read(JmeImporter im) throws IOException {
        InputCapsule capsule = im.getCapsule(this);
        someIntValue   = capsule.readInt("someIntValue", 1);
        someFloatValue = capsule.readFloat("someFloatValue", 1);
        someString = capsule.readString("someString", null);
        //someJmeObject  = capsule.readSavable("someJmeObject",  new Material());


I don’t use the im/exporter you have there, but SaveGame,
but it looks like you forgot to add implements Savable
to your custom class.

You’re using getChildren().get(0), which isn’t exactly a good way to get a child. Maybe you’re just grabbing the wrong one?

Hi Robbi,

I implemented Savable

public class FirstModel implements Savable {

Hi Normen,

Yeah my getter choice is not really good but it was just for testing. I checked a lot of time with Intellij debeuger and I’m sure to grab the good one.