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

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

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

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

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

0

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

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

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

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

0

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

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.