English translation of the article by Joaquin del Cerro.
Hi,
A developer has asked in the gvSIG´s development list how he could add a new entry to the “preferences dialog of gvSIG” to manage the preferences of a plugin.
I am going to quickly explain how you could do this, along with where and how these preferences would be stored.
I will begin with where the plugin´s preferences should be stored. If gvSIG 2.1.0 is installed we can have a quick look at the gvSIG folder in “HOME”, where there will be a “plugins” folder, which contains one folder for each plugin. There won´t be one for each GVSIG plugin ,however there will be one folder for each plugin that needs to store preferences or information that must be updated during the running of gvSIG. If we Look inside the folder:
gvSIG/plugins/org.gvsig.coreplugin.app.mainplugin/
of “HOME”.
There we find the “plugin-persistence.dat” file. Ahí es donde cada plugin almacena sus datos relacionados con preferencias. This is the file where each plugin stores its data related to preferences. The format of this file is similar to the project files of gvSIG (.gvsproj), but it stores a different kind of information, and this one is particular for each plugin.
If we erase these files we will lose our preferences and the device will be started with the default values from the code. This file is matched with another that is located in the plugin folder.If we look in the folder:
gvSIG/extensiones/org.gvsig.coreplugin.app.mainplugin/
…of our installation of gvSIG, we will find a file “plugin-persistence.def” with the file´s definition “plugin-persistence.dat” stored in “HOME/gvSIG…”. For example, with “org.gvsig.coreplugin.app.mainplugin”, we will have something like:
<?xml version="1.0"?> <definitions> <version>1.0.0</version> <classes> <class name="org.gvsig.coreplugin.app.mainplugin"> <description>Persistence for the core plugin</description> <fields> <field name="showNotificationsInConsole" type="Boolean" defaultValue="false" mandatory="false"> <description></description> </field> <field name="showNotificationsInStatusbar" type="Boolean" defaultValue="true" mandatory="false"> <description></description> </field> </fields> </class> </classes> </definitions>
Here we have defined that in the preferences of the plugin there are two properties of type “boolean“, “showNotificationsInConsole” and “showNotificationsInStatusbar” and their default values are “false” and “true” respectively.
The first step to manage the preferences of our plugin will be to create this file with the definition of the attributes that we want to have in our preferences. For values “simples“, String, Integer, Double, Boolean… the definition is very simple, but we can store more complex data structures like “List“, “Map” o “Set“, and if we need we can define our own estructure. For now, I think the “simple” type taking a look at the files “plugin-persistence.def” is enough,which you can find in the installation of gvSIG. If you have any questions ask for the development list. If I have time and people think it would be interesting, I will prepare an article commenting in detail on all the possibilities we have to define our preference data in this file.
One important thing to note… it is very important that we put “<class name=” and you put the exact same name of the plugin if not, it won´t load with it.
Ok, I assume that you have created your file “plugin-persistence.def”, and it is ready for dropping in the installation folder of your plugin. Now what can I do with it?
It is very simple. We are going to see some code:
PluginsManager pluginsManager = PluginsLocator.getManager(); PluginServices plugin = pluginsManager.getPlugin(MyClaseExtension.class); DynObject pluginProperties = plugin.getPluginProperties();
With these three lines, we would force the loading of the file, if it existed “plugin-persistence.dat”. If it didn´t exist, an empty new “structure” would be created with the definition of “plugin-persistence.def” and ne would be left in “pluginProperties” for us to acces. We could do:
Boolean showNotificationsInStatusbar = (Boolean) pluginProperties.getDynValue("showNotificationsInStatusbar")
To access the “showNotificationsInStatusbar” property of our preferences file. Or if we wanted we could do:
pluginProperties.setDynValue("showNotificationsInStatusbar", Boolean.TRUE);
If we wanted to assign a value to the property of our preferences. If we change the preference settings, you can force to save them at that moment with:
pluginProperties.savePluginProperties()
Or simply, when gvSIGis closed, these are saved automatically.
So it would be a very quick plan to can save or recover our plugin preferences. Now, what remains is to see how we can add a new entry to manage these preferences to the preferences dialogue of the application.
To create an entry in the preferences of gvSIG, we have to create a class that extends to the “AbstractPreferencePage” and fill in some methodology:
public class MyreferencesPage extends AbstractPreferencePage { private static final Logger logger = LoggerFactory.getLogger(MyPreferencesPage.class); public static final String ID = MyreferencesPage.class.getName(); private MyPreferencesPanel preferences; private DynObject pluginProperties; private PluginServices plugin; public MyPreferencesPage() { initComponents(); } private void initComponents() { I18nManager i18nManager = ToolsLocator.getI18nManager(); PluginsManager pluginManager = PluginsLocator.getManager(); this.plugin = pluginManager.getPlugin(this); this.pluginProperties = this.plugin.getPluginProperties(); this.preferences = new MyPreferencesPanel(); ... this.setLayout(new BorderLayout()); this.add(this.preferences, BorderLayout.NORTH); initializeValues(); } public void storeValues() throws StoreException { // We get the values from our pannel and // we save them in "pluginProperties" ... this.plugin.savePluginProperties(); } public void setChangesApplied() { } public String getID() { return ID; } public String getTitle() { I18nManager i18nManager = ToolsLocator.getI18nManager(); return i18nManager.getTranslation("Title of our page"); } public JPanel getPanel() { return this; } public void initializeValues() { // We load our stored data in preferences, // "pluginProperties", at the controls of user interface ... Boolean showNotificationsInStatusbar = (Boolean) pluginProperties.getDynValue("showNotificationsInStatusbar"); ...setSelected(showNotificationsInStatusbar.booleanValue()); ... } public void initializeDefaults() { } public ImageIcon getIcon() { return IconThemeHelper.getImageIcon("my-preferences"); } public boolean isValueChanged() { // If user has changed any value of our page // we will return "true" to recover them and // to be saved. In other case we will return "false" boolean changed = false; ... return changed; } public boolean isResizeable() { // The usual thing is to return true. // It indicates that the pannel will be at the dialog using a // layout that resizes it. return true; } }
If we wanted that our preferences site to be “under” another one in the tree that appears on the preferences dialog, we would have to add to the construction of our class a call to “setParentID” indicating the ID of the page below the one we want to be our page. For example:
public MyPreferencesPage() { setParentID(GeneralPage.id); initComponents(); }
Our page would be located under “General” entry of the preferences dialog.
When we have created our class, we just have to register the gvSIG to be aware of it and it will be presented. To do this, in the “initialize” method of our extension, we can use something similar to these lines of code:
ExtensionPointManager extensionPoints =ToolsLocator.getExtensionPointManager(); ExtensionPoint ep = extensionPoints.add("AplicationPreferences", ""); ep.append("MyPage", "", new MyPreferencesPage());
Now, we just need to compile everything and see what happens.
I hope this has helped.
Bye¡¡