The GenericDialog class is part of ImageJ1 and can be used to make simple graphical user interfaces for scripts and plugins. It requires a bit more of work than with the script parameters option but offers more possibilities.
Fiji offers an additional GenericDialogPlus subclass which include additional GUI item like a file input with a browse button.
Like the script parameters, plugins using the Generic Dialog (or one of its subclass) are macro recordable.
Here is an example in Jython.
from ij.gui import GenericDialog # Create an instance of GenericDialog GUI = GenericDialog("My first GUI") # Add some GUI elements (Ok and Cancel button are present by default) # Elements are stacked on top of each others by default (unless specified) GUI.addMessage("Some information to display at the top of the GUI") GUI.addStringField("Type some input text :", "initial text") GUI.addCheckbox("This is a tickbox->Activate some option", True) # We can add elements next to each other using the addToSameRow method GUI.addToSameRow() # The next item is appended next to the tick box GUI.addChoice("Choose one option among a list", ["Choice1", "Choice2"], "Choice1") # Choice1 is default here GUI.addNumericField("Some integer", 10, 0) # 0 for no decimal part # Add a Help button in addition to the default OK/Cancel GUI.addHelp(r"https://imagej.net/Generic_dialog") # clicking the help button will open the provided URL in the default browser # Show dialog, the rest of the code is not executed before OK or Cancel is clicked GUI.showDialog() # dont forget to actually display the dialog at some point # If the GUI is closed by clicking OK, then recover the inputs in order of "appearance" if GUI.wasOKed(): inString = GUI.getNextString() inBool = GUI.getNextBoolean() inChoice = GUI.getNextChoice() # one could alternatively call the getNextChoiceIndex too inNum = Win.getNextNumber() # This always return a double (ie might need to cast to int)
Image and file inputs
By default, script and plugins process the last selected image.
However sometime one needs to specify different images or files as input.
The subclass GenericDialogPlus provides a couple of handful methods for such cases, while all methods shown above are inherited from the GenericDialog class.
from fiji.util.gui import GenericDialogPlus # Create an instance of GenericDialogPlus GUI = GenericDialogPlus("an enhanced GenericDialog") # Add possibility to choose some images already opened in Fiji GUI.addImageChoice("Image1","Some description for image1") GUI.addImageChoice("Image2","Some description for image2") # The GenericDialogPlus also allows to select files, folder or both using a browse button GUI.addFileField("Some_file path", "DefaultFilePath") GUI.addDirectoryField("Some_folder path", "DefaultFolderPath") GUI.addDirectoryOrFileField("Some_Path", "DefaultPath") GUI.showDialog() # Recover the inputs in order of "appearance" if GUI.wasOKed(): ImpImage1 = GUI.getNextImage() # This method directly returns the ImagePlus object ImpImage2 = GUI.getNextImage() # Path are recovered as string FilePath = GUI.getNextString() FolderPath = GUI.getNextString() SomePath = GUI.getNextString()
Just like script parameters, plugins using the GenericDialog class are macro-recordable.
One important thing to note is the name of the variable in the recorded command. This name is actually the first word of the string used as label for each item, with lowercase letters only.
A single word is not very intuitive to understand a parameter in most cases. To include the next words of the label in the recorded command replace the space with underscores, as in
For instance the previous code saved as
Fiji.app/scripts/Plugins/Test yields the following recorded command:
run("GUI ", "image1=MyImage1.tif image2=MyImage2.tif some_file=DefaultFilePath some_folder=DefaultFolderPath some_path=DefaultPath");
Recalling previous entries using the PrefService
It is convenient to have the previously entered parameters recalled at the next run of a given plugin. This is happening automatically for Script parameters (unless specified differently) but not for the GenericDialog class.
Fortunately, it is still possible to make it works using the PrefService.
Services are some ImageJ2/SciJava features that can be though as some kind of package import at runtime. Here's the link to the PrefService.
And below is a Jython example of how to use it.
#@ PrefService prefs from fiji.util.gui import GenericDialogPlus # Create GUI Win = GenericDialogPlus("Some GUI") Win.addImageChoice("Image", prefs.get(None, "Image", "DefaultImage") ) Win.addCheckbox("Activate some option", prefs.getInt(None, "doOption", False) ) # in theory we should use the getBoolean method but it does not work for Jython, the wrong method signature is matched Win.addStringField("Some_string", prefs.get(None, "someString", "initial")) Win.addChoice("Some_choice", ["Choice1","Choice2"], prefs.get(None, "someChoice", "DefaultChoice")) Win.addNumericField("Some_integer", prefs.getInt(None, "N", 1), 0) Win.addNumericField("Some_float", prefs.getFloat(None, "Decimal", 0.5), 2) Win.showDialog() if Win.wasOKed(): image = Win.getNextImage() doOption = Win.getNextBoolean() someString = Win.getNextString() someChoice = Win.getNextChoice() N = int(Win.getNextNumber()) # cast to int : getNextNumber always return a double Decimal = Win.getNextNumber() # Save in memory using PrefService prefs.put(None, "Image", image.getTitle()) prefs.put(None, "doOption", doOption) prefs.put(None, "someString", someString) prefs.put(None, "someChoice", someChoice ) prefs.put(None, "N", N) prefs.put(None, "Decimal", Decimal)
The first step is to "import" the PrefService and to assign it a name, here prefs.
Then there are 2 methods to respectively recover and store some parameter values from the PrefService, namely
Let's start with
get. This method is define for the different datatype
getBoolean. An exception for String there is no
Also in Jython the
getBoolean method is not mapping the right Java signature, so use
getInt instead as illustrated above.
There are 3 arguments for the
- the 1st one is the Plugin class for which to associate the parameter persistence. Leave it None (or Null in other languages) to use the default.
- the 2nd argument is the name of the variable to recall from memory/the preferences, it should be the same name used by the
put method for that parameter.
- the last parameter is the default value to use if no variable with such name exist in memory ie the first time you run your script or if you reset the preferences.
put is even simpler as there is only a single method that takes also 3 arguments:
- The 1st is like for
get an optional Plugin class
- The 2nd argument is the name used to store the parameter value in memory/in the preferences, it is the same name used by
get to recover the previously entered value.
- The 3rd value is the value to store in memory with the name in argument 2. If the parameter was already existing in memory the value is updated to this newly provided value.
Therefore in the script above, the default values for the GenericDialog fields are initialized to the values available in memory, or some default values if there are missing in memory.
Once the GUI is oked, the values in memory are updated with the newly typed values, using the