Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: How to deal with custom settings in plugins for my application?

I'm currently working on an application which receives commands from other devices. I will provide an interface to let others develop their own interpretation (plugin) of the incoming commands. Each of the plugins developed by others can have any custom settings which need to be provided by the users.

For instance, a plugin called "KeyboardPlugin" could support settings to set the delay between key-presses, but also show a list of all supported keys to press. Another plugin could be for instance called "MouseMovePlugin" where the user could select the accuracy of the mouse and its speed.

Now my problem is, that the settings for each plugin need to be 1. shown in the UI, 2. after the settings were selected by the user, they have to be parsed back to the plugin to let the plugin know what the user selected.

I'm working with Java and the UI is developed in Swing. There is a options panel which shows options which do not directly relate to the plugin, like common options. But on the same panel, I want to show the settings provided by the plugin.

The plugin settings look like this:

  • a)"Please enter the delay between two key presses -> [Textbox with Int as input] (with min 1; max 500)
  • b) "bla bla -> [Checkbox] (with boolean)"
  • c) "Bla bla 2 -> [Textbox] (with String values as input; relates on setting b!)
  • d) "Choose button to press" ["a","b","c"]

As you can see, plugin settings can for instance be type int, boolean, string, but also like example d, a array or enum. My problem now is, how can I handle this? Each plugin can have a set of setting types which also could depend on each other, like example c depends on the user choice of b.

1)First I need a technique to ask the plugin for its settings, well, I could just call a method provided in the plugin interface, but what should it return? I mean, a List could work but then there is no dependency between settings options.

2) How do I then "set the settings in the plugin". If the user selects his/her preferred settings, then how do I tell the plugin about?

The only solution which I could figure out in my head until now is the following: A simple domain specific language (DSL) which is like this: varName: type(min,max,default) "UI question" as a given example:

buttonDelay: boolean(false) "Enable button delay"
if(buttonDelay){
buttonDelayTime: int(1,500,25) "Choose delay between buttons"
}

I would parse the settings DSL into a Java tree to be able to have a simple type checking and to use the tree also to generate the settings UI panel. If the user then selects the settings he wants to have (which could be a subset of the provided settings by the plugin, as he/she must not use all provided settings), I would parse a Map to the plugin, like Map, where the Key is the varName (from the example: "buttonDelay" and "buttonDelaytime"). And I would probably have multiple containers for the different settings type, like for a Integer setting, there is a container, but also for boolean, array etc. By parsing the map to the plugin, the plugin could ask the map for the settings for each settings varName, for instance like:

public void initPluginSettings(Map<String,SettingsInterface> settingsMap){
BooleanSetting buttonDelay = settingsMap.get("buttonDelay"); 
IntegerSetting buttonDelayTime = settingsMap.get("buttonDelayTime");
}

Does somebody has a simpler / smarter possible solution? Or are there some patterns for this problem? I already searched the web but I couldn't really find something. To implement a DSL, use the tree to type check etc. seems a bit "too much" for me for this problem. I mean, I could do this but I would love to get others peoples suggestions before I start.

Thank you in advance!

like image 217
Luka Hale Avatar asked Oct 21 '22 15:10

Luka Hale


2 Answers

how about something like:

interface Plugin {
  Map<String, String> getSettingsList();
  getPossibleValuesFor(String key);
  setValue(String key, .. value);
  .. getValue();
}

getSettingsList() would return a map from keys to types; getPossibleValuesFor() is there so the plugin developer can restrict the default range of the types or impose dependencies between settings. And then add persistence to it.

like image 197
miki Avatar answered Oct 27 '22 18:10

miki


How about something like:

Interface Plugin extends Serializable
{
    // You don't know what the plugin is, the possible options, or how best to set them. Let plugin developers build their own settings UI, you just grab and display it in your own JPanel.
    public JPanel getOptionsPanel();

    // We don't know the types of data that can be returned from plugins, so build a map of the setting name to what the user set it to, and return that to the plugin itself.
    public Map<String, Object> getUserSettings();
}

This puts the burden off of you for trying to figure out how to display plugin settings. For each plugin, get its options panel, and add it to yours. Then you can just return the option names and values back to the plugin to deal with.

like image 45
Eric Hydrick Avatar answered Oct 27 '22 17:10

Eric Hydrick