Add Multiple Select parameter
It would be useful to have a Multiple Select parameter in addition to the single choice that is possible with String parameters and the choices annotation.
Maybe this could be implemented as a new SelectionWidget with two styles:
- a list of checkboxes
- a textbox list with the possibility to select multiple lines
What do you think?
@imagejan What would you suggest for the underlying data structure? I.e.: the actual type of the parameter?
Maybe String[] or List<String>?
I took a look, but this is a bit tricky type-wise.
The ModuleItem interface defines the following API:
/** Gets the list of possible values. */
List<T> getChoices();
/** Gets the item's current value with respect to the given module. */
T getValue(Module module);
/** Sets the item's current value with respect to the given module. */
void setValue(Module module, T value);
Suppose we have a parameter like this:
@Parameter(choices = {"Alice", "Bob", "Charlie"})
List<String> names;
The type T of the parameter is List<String>, which makes sense for getValue and setValue, but getChoices in this case returns List<List<T>> so we would have to—I guess—return each name in its own singleton list. I do not believe such a conversion currently happens. And it is a bit misleading since the idea of "choices" now changes: it does not imply the value must equal one and only one of the choices given anymore.
But some hackish solution still seems feasible on the surface, so I started trying to implement something. But it does not work yet.
And here is the Groovy script I used for testing:
// @String(choices = {"quick", "brown", "fox"}) single
// @java.util.List(choices = {"the", "lazy", "dog"}) multiple
println("single = " + single)
println("multiple = " + multiple)
But it does not work yet.
Right, I get:
java.lang.NullPointerException
at org.scijava.widget.DefaultWidgetModel.getChoices(DefaultWidgetModel.java:234)
As far as I get it, choicesList.get(i) seems to be null here:
https://github.com/scijava/scijava-common/blob/f7457f0e0538a9f61b25ffe43988660766e14a7a/src/main/java/org/scijava/widget/DefaultWidgetModel.java#L234
... so item.getChoices() seems to return a list of null values ?!
so item.getChoices() seems to return a list of null values
Yep.
Upon further thought, I think changing the implicit contract for getChoices() is not the way to go here. That method is supposed to return a list of constrained values for the item, and I don't want to pervert that here.
Instead, we should expand the ModuleItem API to add new method(s) with something like getPossibleElements() that returns, I dunno, I guess just List<Object>, since there is no way to decompose the T here. Alternately we could make a new ModuleListItem<E> extends ModuleItem<List<E>> although that comes with its own challenges.
This project is, unfortunately, too involved for me to tackle any time soon. It requires some experimentation, together with careful thought about the API and implications.
This issue has been mentioned on Image.sc Forum. There might be relevant details there:
https://forum.image.sc/t/how-to-customize-override-scijava-ui/43642/4