scijava-common icon indicating copy to clipboard operation
scijava-common copied to clipboard

Add Multiple Select parameter

Open imagejan opened this issue 8 years ago • 6 comments

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 avatar Mar 28 '17 14:03 imagejan

@imagejan What would you suggest for the underlying data structure? I.e.: the actual type of the parameter?

ctrueden avatar Mar 29 '17 13:03 ctrueden

Maybe String[] or List<String>?

imagejan avatar Mar 29 '17 14:03 imagejan

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)

ctrueden avatar Apr 11 '17 21:04 ctrueden

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 ?!

imagejan avatar Apr 12 '17 09:04 imagejan

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.

ctrueden avatar Apr 12 '17 15:04 ctrueden

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

imagesc-bot avatar Oct 06 '20 12:10 imagesc-bot