Persisting State of Components

I'm trying to follow these instructions:
http://confluence.jetbrains.net/display/IDEADEV/Persisting+State+of+Components

But I don't understand how this works, should I register my class somewhere? I've created a new class, implemented PersistentStateComponent with the @State annotation, but the getState and loadState methods are never fired.

If I put the implements in my ProjectComponent then the getState is executed automatically on startup, but I'm getting an Exception after returning "this":
Could not save project:
java.lang.InstantiationException
myPackage.myProjectComponent

What I'm doing wrong?

9 comments
Comment actions Permalink

Hi Enrique,

You should register your persistent class within the DI container. E.g. add the following for project-scoped settings to your plugin.xml:

<projectService serviceImplementation="YourStateClass"/>


Denis

0
Comment actions Permalink

Thanks for your reply Denis, but it didn't work.

I've added the <projectService> inside my <extensions defaultExtensionNs="com.intellij">

But the getState and loadState() are never called.

I don't understand how does this work.

How does the ide know that it must call the getState and loadState from my class? where I'm telling that?

Strangely if I implement PersistentStateComponent in my <projectConfigurable/> class, the getState and loadState methods are called (even without any <projectService>) but it doesn't work, it's throwing an error how I said in my first post.

Please can you post more details of how to implement this?

Thanks !

0
Comment actions Permalink

The requirements are as follows:

  • make target class implement PersistentStateComponent;
  • define where the data should be stored (via the @State annotation);
  • register the class at the plugin.xml;

If you have done the following and the problem still persist you can attach a sample project, we'll take a look.

Denis

0
Comment actions Permalink

Project services are not instantiated unless someone requests them. If you simply declare a project service and never access it from any other code, it will never be created, and therefore the getState/loadState methods will never be called.

0
Comment actions Permalink

Well, I'm really lost, I don't know what to try, this is what I'm doing:

plugin.xml:

  <extensions defaultExtensionNs="com.intellij">
    <projectConfigurable instance="com.enrique.forms.SettingsForm"></projectConfigurable>
    <projectService serviceImplementation="com.enrique.MyCustomSettings"/>
  </extensions>


@State(
        name = "MyCustomSettings",    // must be equal to the class name
        storages = {
                @Storage(id = "default", file = "$PROJECT_FILE$"),
                @Storage(id = "dir", file = "$PROJECT_CONFIG_DIR$/mycustomsettings.xml", scheme = StorageScheme.DIRECTORY_BASED)
        }
)
public class MyCustomSettings implements PersistentStateComponent<MyCustomSettings> {

    public String something;

    public static MyCustomSettings getInstance() {
        return ServiceManager.getService(MyCustomSettings.class);      // this returns null
    }

    @Override
    public MyCustomSettings getState() {
        return this;
    }

    @Override
    public void loadState(MyCustomSettings state) {
        XmlSerializerUtil.copyBean(state, this);
    }

    @Nullable
    private Project guessProject() {
        return ProjectUtil.guessCurrentProject(null);
    }


}


and inside my Form

@Override
    public JComponent createComponent() {

        MyCustomSettings settings = MyCustomSettings.getInstance();         // this returns null

        //myField.setText(settings.something);
        myComponent = (JComponent) myPanel;
        return myComponent;

    }


what I'm doing wrong?

Thanks !

0
Comment actions Permalink

Your service is registered as a project service so you need to use ServiceManager.getInstance(project, aClass) method. The
ServiceManager.getInstance(aClass) method is used to obtain instances of application-level services.

--
Nikolay Chashnikov
Software Developer
JetBrains, Inc
http://www.jetbrains.com
"Develop with pleasure!"

0
Comment actions Permalink

Thanks ! it's working now !

0
Comment actions Permalink

ServiceManager.getInstance() seems depreciated and keeps giving me null pointer exception, any clue why?

0
Comment actions Permalink

The replacement for the deprecated APIs is documented in the javadoc comments: `Application.getService()` and `Project.getService()`. For the null pointer exception, we'd need to see the complete stacktrace in order to explain why it happens

0

Please sign in to leave a comment.