Masking @Parameter from GUI harvesting ?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Masking @Parameter from GUI harvesting ?

Adrian Daerr
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
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Masking @Parameter from GUI harvesting ?

Curtis Rueden
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




On Sun, Aug 23, 2015 at 6:44 AM, Adrian Daerr <[hidden email]> 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
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Masking @Parameter from GUI harvesting ?

Adrian Daerr
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 <[hidden email]> 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 <
> [hidden email]> 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
>> [hidden email]
>> http://imagej.net/mailman/listinfo/imagej-devel
>>

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

_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel
Reply | Threaded
Open this post in threaded view
|

Re: Masking @Parameter from GUI harvesting ?

Curtis Rueden
Hi Adrian,

> 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.

Checking inside preview() is the approach I favor in general, because your constraints on what triggers a preview recomputation could be based on anything.

That said, perhaps it would make sense to make the really common case easy: add a flag "boolean preview" to the @Parameter annotation (and corresponding ModuleItem#isPreviewed() method). I filed an issue:


> 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:

More generally, it would be nice if you could annotate min and/or max as an exclusive bound rather than an inclusive one. This would solve your non-zero problem. Issue filed:


Regards,
Curtis

On Thu, Aug 27, 2015 at 10:35 AM, Adrian Daerr <[hidden email]> wrote:
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 <[hidden email]> 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 <
[hidden email]> 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
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel


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


_______________________________________________
ImageJ-devel mailing list
[hidden email]
http://imagej.net/mailman/listinfo/imagej-devel