Skip to content

Commit 62d878b

Browse files
committed
Harvest convertible module inputs
When harvesting inputs via WidgetModel, inputs that are convertible to the desired type will now be added to the object pool and automatically converted when set as a module input's value.
1 parent 009313f commit 62d878b

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/main/java/org/scijava/widget/AbstractInputHarvester.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.List;
3636

3737
import org.scijava.AbstractContextual;
38+
import org.scijava.convert.ConvertService;
3839
import org.scijava.module.Module;
3940
import org.scijava.module.ModuleCanceledException;
4041
import org.scijava.module.ModuleException;
@@ -63,6 +64,9 @@ public abstract class AbstractInputHarvester<P, W> extends AbstractContextual
6364
@Parameter
6465
private ObjectService objectService;
6566

67+
@Parameter
68+
private ConvertService convertService;
69+
6670
// -- InputHarvester methods --
6771

6872
@Override
@@ -142,9 +146,13 @@ private <T> WidgetModel addInput(final InputPanel<P, W> inputPanel,
142146
return null;
143147
}
144148

145-
/** Asks the object service for valid choices */
146-
private <T> List<T> getObjects(final Class<T> type) {
147-
return objectService.getObjects(type);
149+
/** Asks the object service and convert service for valid choices */
150+
@SuppressWarnings("unchecked")
151+
private List<?> getObjects(final Class<?> type) {
152+
@SuppressWarnings("rawtypes")
153+
List compatibleInputs = convertService.getCompatibleInputs(type);
154+
compatibleInputs.addAll(objectService.getObjects(type));
155+
return compatibleInputs;
148156
}
149157

150158
}

src/main/java/org/scijava/widget/WidgetModel.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,13 @@
3333

3434
import java.util.Arrays;
3535
import java.util.List;
36+
import java.util.Map;
37+
import java.util.WeakHashMap;
3638

3739
import org.scijava.AbstractContextual;
3840
import org.scijava.Context;
3941
import org.scijava.ItemVisibility;
42+
import org.scijava.convert.ConvertService;
4043
import org.scijava.log.LogService;
4144
import org.scijava.module.MethodCallException;
4245
import org.scijava.module.Module;
@@ -59,10 +62,14 @@ public class WidgetModel extends AbstractContextual {
5962
private final Module module;
6063
private final ModuleItem<?> item;
6164
private final List<?> objectPool;
65+
private final Map<Object, Object> convertedObjectPool;
6266

6367
@Parameter
6468
private ThreadService threadService;
6569

70+
@Parameter
71+
private ConvertService convertService;
72+
6673
@Parameter(required = false)
6774
private LogService log;
6875

@@ -76,6 +83,7 @@ public WidgetModel(final Context context, final InputPanel<?, ?> inputPanel,
7683
this.module = module;
7784
this.item = item;
7885
this.objectPool = objectPool;
86+
convertedObjectPool = new WeakHashMap<Object, Object>();
7987
}
8088

8189
/** Gets the input panel intended to house the widget. */
@@ -159,7 +167,25 @@ public Object getValue() {
159167
public void setValue(final Object value) {
160168
final String name = item.getName();
161169
if (MiscUtils.equal(item.getValue(module), value)) return; // no change
162-
module.setInput(name, value);
170+
171+
// Check if a converted value is present
172+
Object convertedInput = convertedObjectPool.get(value);
173+
if (convertedInput != null &&
174+
MiscUtils.equal(item.getValue(module), convertedInput))
175+
{
176+
return; // no change
177+
}
178+
179+
// Pass the vale through the convertService
180+
convertedInput = convertService.convert(value, item.getType());
181+
182+
// If we get a different (covnerted) value back, cache it weakly.
183+
if (convertedInput != value) {
184+
convertedObjectPool.put(value, convertedInput);
185+
}
186+
187+
module.setInput(name, convertedInput);
188+
163189
if (initialized) {
164190
threadService.run(new Runnable() {
165191

@@ -363,6 +389,11 @@ private Object ensureValidObject(final Object value) {
363389
private Object ensureValid(final Object value, final List<?> list) {
364390
for (final Object o : list) {
365391
if (o.equals(value)) return value; // value is valid
392+
// check if value was converted and cached
393+
final Object convertedValue = convertedObjectPool.get(o);
394+
if (convertedValue != null && value.equals(convertedValue)) {
395+
return convertedValue;
396+
}
366397
}
367398

368399
// value is not valid; override with the first item on the list instead

0 commit comments

Comments
 (0)