Fetch ImageJ1 ResultsTable in ImageJ2 Command




@imagejan @NicoKiaru @stelfrich @ctrueden

Is it possible to fetch an IJ1 ResultsTable in an IJ2 command?

I tried like this, but neither seems to work:

@Parameter ( label = "Results table" )
public net.imagej.table.ResultsTable resultsTable;

@Parameter ( label = "Results table" )
public ij.measure.ResultsTable resultsTable;

The first one works, but only for the new ResultsTables and the second one does not produce an UI element. Am I doing something wrong or is it simply not implemented?


What do you mean by “works”? The following Groovy script:

#@ net.imagej.table.ResultsTable rt

println rt

results in the message “A ResultsTable required but none exist.” for me, which is expected because the ObjectService doesn’t know any object of this class.

For IJ1 ResultsTables, there’s currently only a SingleInputPreprocessor, namely ResultsTablePreprocessor in imagej-legacy.

This means that the parameters is filled with the currently active ResultsTable (the one named “Results”), as ImageJ 1.x traditionally only knows one results table.

If you want to be able to choose between several open results tables:

  • something in ImageJ (probably in addition to the window manager) needs to be aware of all currently open results tables, e.g. the ObjectService, or
  • a dedicated ResultsTableInputWidget implements InputWidget<ResultsTable> would have to be created (only necessary if you want something else than the default choice widget created for objects known to ObjectService.

If you think something like this would be useful, I’d vote to keep track of org.scijava.table.Table objects and offer a widget for them, but leave the current behavior of ij.measure.ResultsTable unchanged.


Thanks for the answer!
One use case is choosing from several ij.measure.ResultsTable as produced by MorphoLibJ (@iarganda @dgault ). In this case the tables have more meaningful names than the default “Results”, however programmatically those are ij.measure.ResultsTable

  1. As far as I know, keeping track of those tables with an IJ2 ObjectService is not too hard, but it would mean adding some code to MorpholibJ, right? Maybe OK for @iarganda @dgault? @imagejan, could you point us to an example?
  2. Regarding the UI element, is that something that “I can do”? I mean, is the framework extensible in a sense that this could be added during run-time or would it have to be added to some core library?


The problem is that ImageJ1 doesn’t deal well with multiple results tables. In order to access a non-standard results table, you have to rename it to “Results” (and temporarily rename any other Results table to some other name).

To get closer to what you want, we need to consider several steps:

  • Get a list of all ij.measure.ResultsTable instances:
    • Loop over all elements of WindowManager.getNonImageWindows()
    • Check if the returned Frame is an instance of TextWindow
    • Check if TextWindow.getResultsTable() is not null, then add it to the list
    • (^^^ Is there an easier way of doing the above steps??)
  • Make all these ResultsTable instances known to the ObjectService (so that ChoiceWidget can be used), or directly use this list to populate a to-be-created UI widget.

Probably, imagej-legacy could take care of registering every new results table with the ObjectService, so legacy plugins don’t have to be changed.

Sure, the framework is fully extensible. See some examples:

However, as I said above, you won’t need to implement a new widget if all you need is a drop-down choice of String representations, and we rely on the ObjectService


Using your suggestions it turns out there is a quite simple way without ObjectService (and thus without the need to change anything in MorphoLibJ).

  • Find all ResultsTables as you described and put them internally into a Map< String, ResultsTable >, where the key is the respective title of the table
  • Create a dynamic String input element which lets the user choose among the table titles.
  • Use the Map to retrieve the actual ResultsTable chosen by the user.