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.



@State(   name = "User",   storages = {     @Storage(id = "default", file = "$MODULE_FILE$"),   } ) public class User implements PersistentStateComponent<User>{   public String login = "";   public String password = "";   public void setPassword(String password) {     this.password = password;   }   public void setLogin(String login) {     this.login = login;   }   public String getLogin() {     return this.login;   }   public String getPassword() {     return this.password;   }   public static User getInstance(Project project) {     return PeriodicalTasksCloser.getInstance().safeGetService(project, User.class);   }   @Nullable   @Override   public User getState() {     System.out.println("getState()");     return this;   }   @Override   public void loadState(User state) {     System.out.println("loadState");     XmlSerializerUtil.copyBean(state,this);   } }



<idea-plugin version="22">   <id>com.yourcompany.unique.plugin.id</id>   <name>Plugin display name here</name>   <version>1.0</version>   <vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>   <description><![CDATA[       Enter short description for your plugin here.<br>       <small>most HTML tags may be used</small>       ]]></description>   <change-notes><![CDATA[       Add change notes here.<br>       <small>most HTML tags may be used</small>       ]]>   </change-notes>   <depends>com.intellij.modules.lang</depends>   <extensions defaultExtensionNs="com.intellij">     <projectService serviceInterface="model.User"                serviceImplementation="model.User"/>   </extensions>   <application-components>     <!-- Add your application components here -->     <component>       <implementation-class>control.InitPlugin</implementation-class>     </component>   </application-components>   <!-- please see http://confluence.jetbrains.net/display/IDEADEV/Build+Number+Ranges for description -->   <idea-version since-build="107.105"/>   <actions>     <group id="MyPluasdgin.SampasdleMenu" text="TFS" description="Samasdasdple menu">       <add-to-group group-id="MainMenu" anchor="last"  />       <action id="1" text="Product Backlog" description="A test masdasdenu item" />       <action id="0" text="Settings" description="A test masdasdenu item" />     </group>   </actions> </idea-plugin>


What I'm doing wrong?
10 comments
Comment actions Permalink

Are you actually accessing your User class from somewhere else in your plugin code? Services are initialized on demand, so if you simply register a service and never use it, it won't be created and initialized.

0
Comment actions Permalink

Your PersistentStateComponent needs to be defined in xml file. So I usually make my application component or project component to implement PersistentStateComponent.

Second option is this:

plugin.xml:

 <extensions defaultExtensionNs="com.intellij">
      <applicationService serviceInterface="ru.scratch.ScratchData"
                     serviceImplementation="ru.scratch.ScratchData"/>
 </extensions>




@State(name = "ScratchData", storages = {@Storage(id = "main", file = "$APP_CONFIG$/scratch.xml")})
public class ScratchData implements PersistentStateComponent<ScratchData> {....}

0
Comment actions Permalink

If i call ServiceManager.getService(ScratchData.class), and it is not defined in plugin.xml, then it returns null.

edit: ah, he has it defined, so you must be right.

0
Comment actions Permalink

That's true, but what does it have to do with syt's problem? He does register the service in plugin.xml.

0
Comment actions Permalink

Oh yes, I overlooked it.

And could the problem be that he uses @Storage(id = "default", file = "$MODULE_FILE$")  but loads it using a project and not module.

0
Comment actions Permalink

Thank you guys this helped me a lot in a short time after trying a lot of things.

I always initialized my object by

user = new User();


and thought that it would internally restore the state.

The key to get it working is

User TestUser = ServiceManager.getService(User.class)



besides I edited my storage information to

@State(   name = "User",   storages = {     @Storage(id = "main", file = "$APP_CONFIG$/user.xml"),   } )


edit: and changed my class to application level:

<extensions defaultExtensionNs="com.intellij">
    <applicationService serviceInterface="model.User"
               serviceImplementation="model.User"/>
  </extensions>


Once again many thanks for the help!

0
Comment actions Permalink

If you're storing the settings in the application configuration file, you should register your class as an application level service, not a project level service.

0
Comment actions Permalink

You're right, i forgot to post it, i've edited my post now.

0
Comment actions Permalink

Hi, i want to serialize a map of maps, but idea always says

Could not save application settings: Can't serialize instance of class TFS.model.Options



public class Options implements PersistentStateComponent<Options>{
public Map<String, Map<String,String>> columns = new LinkedHashMap<String, Map<String,String>>(){{

    put("StackRank1", new LinkedHashMap<String, String>(){{put("WorkItem", TreeTableModel.class.getCanonicalName());}});
    put("StackRank2", new LinkedHashMap<String, String>(){{put("String", String.class.getCanonicalName());}});
    put("StackRank3", new LinkedHashMap<String, String>(){{put("Datum", Date.class.getCanonicalName());}});
    put("StackRank5", new LinkedHashMap<String, String>(){{put("Rank", Double.class.getCanonicalName());}});

  }};


  public static Settings getInstance(Project project) {

    return PeriodicalTasksCloser.getInstance().safeGetService(project, Settings.class);
  }

  @Nullable
  @Override
  //Saves all public variables to disk.
  public Options getState() {
    columns.put("StackR3ank2", new LinkedHashMap<String, String>(){{put("Rank22", "asdsad:");}});
    return this;
  }

  //restores state from disk
  @Override
  public void loadState(Options state) {
    XmlSerializerUtil.copyBean(state,this);
  }



Attachment(s):
Bildschirmfoto6.png
0
Comment actions Permalink

There should be a specific exception corresponding to the message box in your idea.log. Could you please post it here?

0

Please sign in to leave a comment.