Hi Curtis,

Thanks for the explanations on how parameters are resolved.

We could add a way to mark parameters which are not desired to be
shown in the dialog box. What is your use case for a parameter you
want to have in the script, but never shown to the user in cases
where it is still null?

Upon reflection I don't see when this would be needed. I
misinterpreted the behaviour of the UI harvester in the case of a
net.imagej.overlay.RectangleOverlay, which was being properly
populated but which caused a strangely useless selector to appear in
the dialog (the selector seemed empty or possibly contained one empty
String). Of course the selector is really only usefull if there were
several RectangleOverlays to chose from, and they had meaningful
labels. In the case only one selection is defined one could just drop
the selector from the dialog. But I thought (should have checked) that
the UI would try to ask for a RectangleOverlay if none were found.
This is not the case: when there is no RectangleOverlay at all the
plugin fails just as in the absence of an image, which is what I want
(the user can then define a selection as usual and call the plugin
again). No need for any new annotation here.

2) A net.imagej.overlay.RectangleOverlay parameter, although properly
populated, provoques an Exception after the execution of the command.
(more details and stacktraces below)

As I mentioned in the other thread: try with Overlay instead? We
could certainly make it autofill parameters with specific Overlay
subclasses too—just need to confirm first that that is indeed your
problem.

No need, the OverlayService.getSelectionBounds() you mention in the
other thread behaves just fine.

3) When a new preview is triggered, and that preview modifies numeric
parameters, then the numeric values visible in the gui dialog are
updated except for the NumericField on which input has triggered the
call to preview().

It is a programming error for the preview() function to modify
parameter values. Use callbacks instead, which occur before
preview() is called [1].

Ok, makes sense.

4) It would be nice if a parameter could have a label even if
ItemVisibility is MESSAGE

Fixed [2].

Great, thanks a lot!

I have two new small comments (not sure they qualify as feature requests as I'm not sure they're necessarily good ideas):

5) Some parameters do not affect the preview, but preview() is called
nevertheless. Can we avoid calculating a new preview in this case ? Of
course we can check inside the preview() body, before performing the
actual calculation, whether any of the relevant parameters have
changed. A second possibility would be to introduce a new @Parameter
annotation to disable the preview() callback. A third way would be
to modify the framework to skip the preview() call on parameters which
register their own callback. It would be this callback's
responsibility to invoque preview() if desired. One could then easily
register an empty callback function on parameters for which preview()
should not be invoqued. The only drawback I see is that plugin authors
may not expect the fact that registering an explicit callback by
annotation unregisters/disables the preview callback. On the other
hand widgets such as Buttons which rely on their callback seem already
excluded from preview() invocation. One advantage is that the
programmer decides at which point in the callback, if at all,
preview() gets called, as opposed to the current situation where the
order is fixed: the specific callback is invoqued before preview().

6) Really a minor detail: If I want a parameter to be strictly
positive (so I can divide by it without checking for zero), it appears
that I need to specify a small non-negative number explicitely in the
min="" annotation:

@Parameter(min = "1e-300") private double capillary_length;

I cannot specify Double.MIN_VALUE because the 'min' attribute requires
a String, nor Double.toString(Double.MIN_VALUE) as it is not a
constant to the compiler. If the constraint of positivity is
sufficiently common to warrant a small hack, one could allow e.g.
"epsilon" or "positive" as special value for the annotation 'min' that
would be translated to <T>.MIN_VALUE

cheers,
Adrian


On Mon, 24 Aug 2015 15:31:07 -0500
 Curtis Rueden <ctrue...@wisc.edu> wrote:
Hi Adrian,

1) How does one prevent a @Parameter from showing up in the harvesting
GUI dialog, in the manner of a '@Parameter LogService log'? (more
below)

Parameters which are resolved before the input harvester dialog pops up
will not show up.

They get resolved by the various preprocessors in the preprocessing chain, which is applied before the module is actually run. The InputHarvester -- which is what pops the dialog box -- is (IIRC) the final preprocessing step
before run happens.

We could add a way to mark parameters which are not desired to be shown in the dialog box. What is your use case for a parameter you want to have in the script, but never shown to the user in cases where it is still null?

2) A net.imagej.overlay.RectangleOverlay parameter, although properly populated, provoques an Exception after the execution of the command.
(more details and stacktraces below)

As I mentioned in the other thread: try with Overlay instead? We could certainly make it autofill parameters with specific Overlay subclasses
too—just need to confirm first that that is indeed your problem.

3) When a new preview is triggered, and that preview modifies numeric
parameters, then the numeric values visible in the gui dialog are
updated except for the NumericField on which input has triggered the
call to preview().

It is a programming error for the preview() function to modify parameter values. Use callbacks instead, which occur before preview() is called [1].

4) It would be nice if a parameter could have a label even if
ItemVisibility is MESSAGE

Fixed [2].

Regards,
Curtis

[1]
https://github.com/scijava/scijava-common/blob/scijava-common-2.44.2/src/main/java/org/scijava/widget/DefaultWidgetModel.java#L167-L169

[2]
https://github.com/scijava/scijava-ui-swing/commit/84c30c045bf3327a424f499f1f2fe867b0d9375e


On Sun, Aug 23, 2015 at 6:44 AM, Adrian Daerr <
adrian.da...@univ-paris-diderot.fr> wrote:

Dear ImageJ developers,

As I slowly learn more about IJ2 @Plugins, I have one question and three
minor comments that I would like to submit to you.

1) How does one prevent a @Parameter from showing up in the harvesting GUI dialog, in the manner of a '@Parameter LogService log'? (more below)

2) A net.imagej.overlay.RectangleOverlay parameter, although properly populated, provoques an Exception after the execution of the command.
(more details and stacktraces below)

3) When a new preview is triggered, and that preview modifies numeric
parameters, then the numeric values visible in the gui dialog are
updated except for the NumericField on which input has triggered the
call to preview().

4) It would be nice if a parameter could have a label even if
ItemVisibility is MESSAGE:
  @Parameter(persist = false,
             visibility = org.scijava.ItemVisibility.MESSAGE,
             label = "Current foo value")
    private double foo = 0;
(currently, at least on my box, the label is not shown in this case)
Obviously a workaround is to build a String with label+foo instead.

cheers,
Adrian



ad 1)
How to prevent a @Parameter from showing up in the harvesting GUI
dialog? Some seem to be masked by default (ImagePlus, LogService), but I did not find the appropriate annotation to make the parameter roi in
the following not show up, although it is already properly populated
by the rectangular selection of the active image ? There is no
meaningful thing I can do with the associated selector in the dialog.

    @Parameter private ImagePlus imp;
    @Parameter private RectangleOverlay roi;
    @Parameter private double a;


ad 2)
A net.imagej.overlay.RectangleOverlay parameter

  @Parameter private RectangleOverlay roi;

is properly populated when the Command is invoqued on an active image containing a rectangular selection. However it provoques an Exception
after the execution of the command, when either the
DefaultPrefService, or the Recorder if a persist=false attribute is
added, apparently tries to record a 'null' value for an option. The
two stacktraces are

  [ERROR] Module threw exception
  java.lang.NullPointerException
        at
java.util.prefs.AbstractPreferences.put(AbstractPreferences.java:224)
        at
org.scijava.prefs.DefaultPrefService.put(DefaultPrefService.java:183)
        at
org.scijava.module.DefaultModuleService.save(DefaultModuleService.java:278)
        at
org.scijava.module.process.SaveInputsPreprocessor.saveValue(SaveInputsPreprocessor.java:74)
        at
org.scijava.module.process.SaveInputsPreprocessor.process(SaveInputsPreprocessor.java:65)
        at
org.scijava.module.ModuleRunner.preProcess(ModuleRunner.java:104)
at org.scijava.module.ModuleRunner.run(ModuleRunner.java:156) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
        at
org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
        at
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

  [ERROR] Module threw exception
  java.lang.NullPointerException
        at ij.plugin.frame.Recorder.addQuotes(Recorder.java:612)
        at ij.plugin.frame.Recorder.recordOption(Recorder.java:362)
at net.imagej.legacy.IJ1Helper.recordOption(IJ1Helper.java:467)
        at
net.imagej.legacy.plugin.MacroRecorderPostprocessor.process(MacroRecorderPostprocessor.java:70)
        at
org.scijava.module.ModuleRunner.postProcess(ModuleRunner.java:116)
at org.scijava.module.ModuleRunner.run(ModuleRunner.java:176) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:126) at org.scijava.module.ModuleRunner.call(ModuleRunner.java:65)
        at
org.scijava.thread.DefaultThreadService$2.call(DefaultThreadService.java:191)
        at
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)

_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel


--
http://www.msc.univ-paris-diderot.fr/~daerr/

_______________________________________________
ImageJ-devel mailing list
ImageJ-devel@imagej.net
http://imagej.net/mailman/listinfo/imagej-devel

Reply via email to