Skip to content, Skip to search

Changes

Tips for developers

2,791 bytes added, 30 January
no edit summary
{{DevelopMenu|tutorials}}An unsorted list of hints that you might find useful:
=== compile Compile & execute Execute a class ==Class =
You do not need to call ''<code>javac'' </code> yourself with a long ''classpath'':
<source lang="bash">
$ ./fiji --javac YourClass.java
</source>
and you can call its <code>main() </code> method just as easy:
<source lang="bash">
$ ./fiji YourClass.class argument1 argument2
</source>
=== rapidly prototype Rapidly Prototype a plugin ==Plugin =
It is often easier to start out with a Jython, JRuby or BeanShell script, as you do not have to care about strict typing, exceptions or recompiling. Just place your script (with the correct extension -- .py, .rb or .bsh) into the plugins/ folder and execute the script. Fiji will always execute the current version of the script, so you can edit and run the script without restarting Fiji.
Once you have working code, you can turn it into a proper plugin (this is easiest with BeanShell, as its syntax is closest to Java already), adding strict typing and exception handling as needed.
=== find Find the .jar file containing File Containing a certain class ==Certain Class =
Sometimes, the compiler complains about a class not having a certain method or interface, but you ''know'' it must contain it. More often than not, that class exists in different versions in your classpath. Find out with
<source lang="bash">
$ ./fiji bin/find-jar-for-class.py the.class.youre.looking.For
</source>
If you want to do that with an installed Fiji (i.e. when bin/ is missing), you can start the [[Script Editor]] and execute a BeanShell like this:
<source lang="java">
import ij.IJ;
.loadClass("the.class.youre.looking.For")
.getResource("For.class").toString());
</source>
This will output the URL to the ''.class'' file, including the path to the enclosing ''.jar'' file.
= Using ImageJ effectively Effectively =
ImageJ has a simple API, but it is also big, so here are a few pointers to some useful parts.
<source lang="java">
ImagePlus image = IJ.openImage(path);
</source>
 
== How to get the current image ==
 
<source lang="java">
ImagePlus img = WindowManager.getCurrentImage(); // current image
ImageProcessor ip = img.getProcessor(); // current slice
</source>
<source lang="java">
ImagePlus image = IJ.createInstancecreateImage("my image", "RGB", 640, 480, 20);
</source>
== How to show a plot ==
ImageJ offers the ''<code>ij.gui.Plot'' </code> class to make a window showing a plot. Use it like this:
<source lang="java">
</source>
To add another plot to the same window, use the ''<code>addPoints()'' </code> method:
<source lang="java">
</source>
You might need to adjust the bounding box if the second plot does not match the bounding box of the first one by using the ''<code>setLimits()'' </code> method before the call to ''<code>plot.draw();''</code>
== Duplicate, or convert between, ''ImageProcessor'' types ==
The ''<code>ImageProcessor'' </code> class has several useful methods: [http://pacificfiji.mpi-cbg.desc/javadoc/ij/process/ImageProcessor.html#duplicate() duplicate()], [http://pacific.mpi-cbgfiji.desc/javadoc/ij/process/ImageProcessor.html#convertToByte(boolean) convertToByte()], [http://pacific.mpi-cbgfiji.desc/javadoc/ij/process/ImageProcessor.html#convertToFloat() convertToFloat()],[http://pacificfiji.mpi-cbg.desc/javadoc/ij/process/ImageProcessor.html#convertToRGB() convertToRGB()], and [http://pacific.mpi-cbgfiji.desc/javadoc/ij/process/ImageProcessor.html#convertToShort(boolean) convertToShort()].
This [http://pacificfiji.mpi-cbg.desc/javadoc/ij/process/ImageProcessor.html class] also has some other goodies, such as methods for convolution.
== How to store settings persistently ==
ImageJ (and therefore Fiji, too) has a way to store key/value pairs persistently, i.e. they are available even after a restart. The settings are stored in a file called ''IJ_Prefs.txt'' in the subdirectory called ''.imagej/'' in your home directory (on Windows, directly in your home directory; on Mac, in ''~/Library/Preferences'').
'''Note:''' the settings are only saved upon <u>regular</u> exit of Fiji; If you kill the process, or if the Java Runtime crashes, they are <u>not</u> saved. You can ask for the settings to be saved explicitly, though.
</source>
'''Note:''' do <u>not</u> use the ''<code>getString()'' </code> or ''<code>getInt()''</code>; These methods do not have any setter methods, and they do <u>not</u> access the same values as the ''<code>get()'' </code> method (''<code>get()'' </code> actually prefixes the keys with a dot)!
== How to turn a number into a string, using a given number of decimal places ==
Use the ''<code>d2s()'' </code> method of the ''<code>ij.IJ'' </code> class:
<source lang="java">
for (int i = 0; i < labels.getItemCount(); i++) {
String label = labels.getItem(i);
int slice = manager.getSliceNumber(label);
Roi roi = table.get(label);
... <do something with the ROI and the slice> ...
}
}
</source>
 
To get just the selected ROIs, use code similar to this:
 
<source lang="java">
import java.awt.List;
...
RoiManager manager = RoiManager.getInstance();
if (manager != null) {
String[] labels = manager.getList().getSelectedItems();
Hashtable<String, Roi> table = (Hashtable<String, Roi>)manager.getROIs();
for (String label : labels) {
int slice = manager.getSliceNumber(label);
Roi roi = table.get(label);
rt.show("Results");
</source>
 
== How to find equivalent API commands between ImageJ1 and ImageJ2?==
[[ImageJ1-ImageJ2 cheat sheet]] is available.
 
= Tips for Graphical User Interface (GUI) programming =
 
== Programming with Swing components ==
 
When programming with Swing, beware that Swing is not thread safe. Swing's golden rule states that:
 
:''Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.''
 
When has a Swing component been realized? When it is visible inside Window or ''JFrame'' that got a call to <code>setVisible(true)</code>. This implies that its <code>paint(Graphics)</code> method has been called or will be called soon.
 
These are the methods that can realize a component, or rather, methods called on a ''Window'' or ''Frame'' or ''JFrame'' that will realize all its children components:
 
<source lang="java">
setVisible(true)
show()
pack() // this might surprise you
</source>
 
There is a class which helps you with all this: [http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html SwingUtilities]. Example: to call <code>pack()</code> from within the constructor (which might or might not be called from the Event Dispatch Thread):
 
<source lang="java">
if (SwingUtilities.isEventDispatchThread())
pack();
else try {
SwingUtilities.invokeAndWait(new Runnable() { public void run() {
pack();
}});
} catch (Exception e) { /* ignore */ }
</source>
 
Information extracted from the [http://web.archive.org/web/20120801194837/http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html Swing guide] (now only available from via web.archive.org as Oracle removed the original docs), additional information can be found in the [http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html Concurrency in Swing] lesson of ''The Java Tutorials''.
8
edits