CINXE.COM

Tips for developers

<!DOCTYPE html> <html> <head> <title>Tips for developers</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3" /> <meta content="ImageJ Wiki" property="og:site_name"> <meta content="Tips for developers" property="og:title"> <meta content="article" property="og:type"> <meta content="The ImageJ wiki is a community-edited knowledge base on topics relating to ImageJ, a public domain program for processing and analyzing scientific images, and its ecosystem of derivatives and variants, including ImageJ2, Fiji, and others." property="og:description"> <meta content="https://imagej.github.io/develop/tips" property="og:url"> <meta content="https://imagej.github.io/media/icons/imagej2.png" property="og:image"> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"> <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> <link rel="manifest" href="/site.webmanifest"> <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5"> <meta name="msapplication-TileColor" content="#da532c"> <meta name="theme-color" content="#ffffff"> <link rel="stylesheet" href="/assets/css/lightbox.min.css" /> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/instantsearch.css@7/themes/algolia-min.css"/> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/dygraphs@2.1.0/dist/dygraph.min.css" /> <link rel="stylesheet" href="/assets/css/main.css" /> <link rel="stylesheet" href="/assets/css/layout.css"/> <link rel="stylesheet" href="/assets/css/includes.css" /> <link rel="stylesheet" href="/assets/css/timeline.css"/> <link rel="stylesheet" href="/assets/css/dock.css"/> <noscript><link rel="stylesheet" href="/assets/css/noscript.css" /></noscript> <link rel="stylesheet" href="/assets/css/page.css" /> </head> <body class="is-preload"> <!-- Top bar --> <section id="top-bar"> <a href="/"><img id="site-logo" src="/media/icons/imagej2.png"></a> <div id="search-panel"> <div id="search-box"></div> </div> </section> <!-- Page-info --> <div class="page-info"> <a href="https://github.com/imagej/imagej.github.io/commits/main/_pages/develop/tips.md">Page history</a> <a href="https://github.com/imagej/imagej.github.io/edit/main/_pages/develop/tips.md">Edit this page</a> <a href="/editing">How do I edit this website?</a></div> <section id="left-column" class="sidebar dock"> <!-- Menu --> <div class="menu dockable"> <div class="drag-handle"></div><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a href="/scripting/clojure">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a href="/scripting/jython">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details open><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details open><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a class="current-page">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/timelines">Timelines</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </section> <section id="right-column" class="sidebar dock"> <!-- Vital stats --> <!-- Table of contents --> <div id="toc" class="toc menu dockable"> <div class="drag-handle"></div> <h3>Page contents</h3> <ul data-toc="#content" data-toc-headings="h1,h2,h3,h4,h5,h6"></ul> </div> </section> <!-- Page title --> <div class="container"> <header class="major special"> <h1>Tips for developers</h1> </header> </div> <!-- Nav bar --> <!-- Main content --> <section id="page" class="main style1"> <div class="container"> <div class="box alt"></div> <div id="content" class="page-content"> <p>An unsorted list of hints that you might find useful.</p> <h1 id="compile--execute-a-class">Compile &amp; Execute a Class</h1> <p>You do not need to call <code class="language-plaintext highlighter-rouge">javac</code> yourself with a long <em>classpath</em>:</p> <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./fiji <span class="nt">--javac</span> YourClass.java </code></pre></div></div> <p>and you can call its <code class="language-plaintext highlighter-rouge">main()</code> method just as easy:</p> <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./fiji YourClass.class argument1 argument2 </code></pre></div></div> <h1 id="rapidly-prototype-a-plugin">Rapidly Prototype a Plugin</h1> <p>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.</p> <p>Of course, it is even more convenient to use the <a href="/scripting/script-editor">Script Editor</a>…</p> <p>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.</p> <h1 id="find-the-jar-file-containing-a-certain-class">Find the .jar File Containing a Certain Class</h1> <p>Sometimes, the compiler complains about a class not having a certain method or interface, but you <em>know</em> it must contain it. More often than not, that class exists in different versions in your classpath. Find out with</p> <div class="language-shell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">$ </span>./fiji bin/find-jar-for-class.py the.class.youre.looking.For </code></pre></div></div> <p>If you want to do that with an installed Fiji (i.e. when bin/ is missing), you can start the <a href="/scripting/script-editor">Script Editor</a> and execute a BeanShell like this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="kn">import</span> <span class="nn">ij.IJ</span><span class="o">;</span> <span class="n">print</span><span class="o">(</span><span class="no">IJ</span><span class="o">.</span><span class="na">getClassLoader</span><span class="o">()</span> <span class="o">.</span><span class="na">loadClass</span><span class="o">(</span><span class="s">"the.class.youre.looking.For"</span><span class="o">)</span> <span class="o">.</span><span class="na">getResource</span><span class="o">(</span><span class="s">"For.class"</span><span class="o">).</span><span class="na">toString</span><span class="o">());</span> </code></pre></div></div> <p>This will output the URL to the <em>.class</em> file, including the path to the enclosing <em>.jar</em> file.</p> <h1 id="using-imagej-effectively">Using ImageJ Effectively</h1> <p>ImageJ has a simple API, but it is also big, so here are a few pointers to some useful parts.</p> <h2 id="how-to-read-a-file-into-an-imageplus">How to read a file into an ImagePlus</h2> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nc">ImagePlus</span> <span class="n">image</span> <span class="o">=</span> <span class="no">IJ</span><span class="o">.</span><span class="na">openImage</span><span class="o">(</span><span class="n">path</span><span class="o">);</span> </code></pre></div></div> <h2 id="how-to-get-the-current-image">How to get the current image</h2> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ImagePlus</span> <span class="n">img</span> <span class="o">=</span> <span class="nc">WindowManager</span><span class="o">.</span><span class="na">getCurrentImage</span><span class="o">();</span> <span class="c1">// current image</span> <span class="nc">ImageProcessor</span> <span class="n">ip</span> <span class="o">=</span> <span class="n">img</span><span class="o">.</span><span class="na">getProcessor</span><span class="o">();</span> <span class="c1">// current slice</span> </code></pre></div></div> <h2 id="making-a-new-image-stack--quickly">Making a new image stack – quickly!</h2> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ImagePlus</span> <span class="n">image</span> <span class="o">=</span> <span class="no">IJ</span><span class="o">.</span><span class="na">createImage</span><span class="o">(</span><span class="s">"my image"</span><span class="o">,</span> <span class="s">"RGB"</span><span class="o">,</span> <span class="mi">640</span><span class="o">,</span> <span class="mi">480</span><span class="o">,</span> <span class="mi">20</span><span class="o">);</span> </code></pre></div></div> <h2 id="how-to-display-an-exception-in-a-window">How to display an exception in a window</h2> <p>This is especially useful on Windows, where you usually do not see the console:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">IJ</span><span class="o">.</span><span class="na">handleException</span><span class="o">(</span><span class="n">exception</span><span class="o">);</span> </code></pre></div></div> <p>This is available since ImageJ 1.43g, as well as the option to set a different exception handler using</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="no">IJ</span><span class="o">.</span><span class="na">setExceptionHandler</span><span class="o">(</span><span class="k">new</span> <span class="no">IJ</span><span class="o">.</span><span class="na">ExceptionHandler</span><span class="o">()</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">handle</span><span class="o">(</span><span class="nc">Throwable</span> <span class="n">exception</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// do something</span> <span class="o">}</span> <span class="o">});</span> </code></pre></div></div> <h2 id="how-to-show-a-plot">How to show a plot</h2> <p>ImageJ offers the <code class="language-plaintext highlighter-rouge">ij.gui.Plot</code> class to make a window showing a plot. Use it like this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Plot</span> <span class="n">plot</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Plot</span><span class="o">(</span><span class="s">"The window title"</span><span class="o">,</span> <span class="s">"labels on the x-axis"</span><span class="o">,</span> <span class="s">"labels on the y-axis"</span><span class="o">,</span> <span class="n">float_array_of_x_values</span><span class="o">,</span> <span class="n">float_array_of_y_values</span><span class="o">);</span> <span class="n">plot</span><span class="o">.</span><span class="na">show</span><span class="o">();</span> </code></pre></div></div> <p>Instead of <em>float</em> arrays, you can also use <em>double</em> arrays.</p> <p>If you need to update the plot at some stage, you need to save the return value of <em>show()</em>:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Plot</span> <span class="n">plot</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Plot</span><span class="o">(</span><span class="s">"The window title"</span><span class="o">,</span> <span class="s">"labels on the x-axis"</span><span class="o">,</span> <span class="s">"labels on the y-axis"</span><span class="o">,</span> <span class="n">float_array_of_x_values</span><span class="o">,</span> <span class="n">float_array_of_y_values</span><span class="o">);</span> <span class="nc">PlotWindow</span> <span class="n">window</span> <span class="o">=</span> <span class="n">plot</span><span class="o">.</span><span class="na">show</span><span class="o">();</span> <span class="c1">// ...</span> <span class="nc">Plot</span> <span class="n">update</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Plot</span><span class="o">(</span><span class="s">"Dummy"</span><span class="o">,</span> <span class="s">"x labels"</span><span class="o">,</span> <span class="s">"y labels"</span><span class="o">,</span> <span class="n">x_values</span><span class="o">,</span> <span class="n">y_values</span><span class="o">);</span> <span class="n">window</span><span class="o">.</span><span class="na">drawPlot</span><span class="o">(</span><span class="n">update</span><span class="o">);</span> </code></pre></div></div> <p>To add another plot to the same window, use the <code class="language-plaintext highlighter-rouge">addPoints()</code> method:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">plot</span><span class="o">.</span><span class="na">addPoints</span><span class="o">(</span><span class="n">float_array_of_x_values</span><span class="o">,</span> <span class="n">float_array_of_y_values</span><span class="o">,</span> <span class="nc">Plot</span><span class="o">.</span><span class="na">LINE</span><span class="o">);</span> </code></pre></div></div> <p>The plots can be drawn in different colors like this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">Plot</span> <span class="n">plot</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Plot</span><span class="o">(</span><span class="s">"The window title"</span><span class="o">,</span> <span class="s">"labels on the x-axis"</span><span class="o">,</span> <span class="s">"labels on the y-axis"</span><span class="o">,</span> <span class="n">float_array_of_x_values</span><span class="o">,</span> <span class="n">float_array_of_y_values</span><span class="o">);</span> <span class="n">plot</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="nc">Color</span><span class="o">.</span><span class="na">RED</span><span class="o">);</span> <span class="n">plot</span><span class="o">.</span><span class="na">draw</span><span class="o">();</span> <span class="n">plot</span><span class="o">.</span><span class="na">addPoints</span><span class="o">(</span><span class="n">float_array_of_x_values</span><span class="o">,</span> <span class="n">another_float_array_of_y_values</span><span class="o">,</span> <span class="nc">Plot</span><span class="o">.</span><span class="na">LINE</span><span class="o">);</span> <span class="n">plot</span><span class="o">.</span><span class="na">setColor</span><span class="o">(</span><span class="nc">Color</span><span class="o">.</span><span class="na">BLUE</span><span class="o">);</span> <span class="n">plot</span><span class="o">.</span><span class="na">draw</span><span class="o">();</span> </code></pre></div></div> <p>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 class="language-plaintext highlighter-rouge">setLimits()</code> method before the call to <code class="language-plaintext highlighter-rouge">plot.draw();</code></p> <h2 id="duplicate-or-convert-between-imageprocessor-types">Duplicate, or convert between, <code class="language-plaintext highlighter-rouge">ImageProcessor</code> types</h2> <p>The <code class="language-plaintext highlighter-rouge">ImageProcessor</code> class has several useful methods: <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html#duplicate&gt;()"><code class="language-plaintext highlighter-rouge">duplicate()</code></a>, <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html#convertToByte(boolean)"><code class="language-plaintext highlighter-rouge">convertToByte()</code></a>, <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html#convertToFloat"><code class="language-plaintext highlighter-rouge">convertToFloat()</code></a>, <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html#convertToRGB()"><code class="language-plaintext highlighter-rouge">convertToRGB()</code></a>, and <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html#convertToShort(boolean)"><code class="language-plaintext highlighter-rouge">convertToShort()</code></a>.</p> <p>This <a href="https://javadoc.scijava.org/ImageJ1/ij/process/ImageProcessor.html">class</a> also has some other goodies, such as methods for convolution.</p> <h2 id="how-to-store-settings-persistently">How to store settings persistently</h2> <p>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 <em>IJ_Prefs.txt</em> in the subdirectory called <em>.imagej/</em> in your home directory (on Windows, directly in your home directory; on Mac, in <em>~/Library/Preferences</em>).</p> <div class="notice" style="font-size: 2; background: #e6e6e6; border-left: 10px solid #901913"><div class="notice-icon"><img src="/media/icons/note.svg" width="32" /></div><div class="notice-content"><p>The settings are only saved upon <em>regular</em> exit of Fiji; If you kill the process, or if the Java Runtime crashes, they are <em>not</em> saved. You can ask for the settings to be saved explicitly, though.</p> </div> </div> <p>Example:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">ij.Prefs</span><span class="o">;</span> <span class="o">...</span> <span class="c1">// save key/value pairs</span> <span class="nc">Prefs</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"my.persistent.name"</span><span class="o">,</span> <span class="s">"Grizzly Adams"</span><span class="o">);</span> <span class="nc">Prefs</span><span class="o">.</span><span class="na">set</span><span class="o">(</span><span class="s">"my.persistent.number"</span><span class="o">,</span> <span class="mi">10</span><span class="o">);</span> <span class="o">....</span> <span class="c1">// retrieve the values (with default values)</span> <span class="kt">int</span> <span class="n">myNumber</span> <span class="o">=</span> <span class="nc">Prefs</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="s">"my.persistent.number"</span><span class="o">,</span> <span class="mi">0</span><span class="o">);</span> <span class="c1">// explicitly save the preferences _now_</span> <span class="nc">Prefs</span><span class="o">.</span><span class="na">savePreferences</span><span class="o">();</span> <span class="o">&lt;</span><span class="n">div</span> <span class="kd">class</span><span class="err">="</span><span class="nc">notice</span><span class="s">" style="</span><span class="n">font</span><span class="o">-</span><span class="nl">size:</span> <span class="mi">2</span><span class="o">;</span> <span class="nl">background:</span> <span class="err">#</span><span class="n">e6e6e6</span><span class="o">;</span> <span class="n">border</span><span class="o">-</span><span class="nl">left:</span> <span class="mi">10</span><span class="n">px</span> <span class="n">solid</span> <span class="err">#</span><span class="mi">901913</span><span class="s">"&gt;&lt;div class="</span><span class="n">notice</span><span class="o">-</span><span class="n">icon</span><span class="s">"&gt;&lt;img src="</span><span class="o">/</span><span class="n">media</span><span class="o">/</span><span class="n">icons</span><span class="o">/</span><span class="n">note</span><span class="o">.</span><span class="na">svg</span><span class="s">" width="</span><span class="mi">32</span><span class="s">"&gt;&lt;/div&gt;&lt;div class="</span><span class="n">notice</span><span class="o">-</span><span class="n">content</span><span class="s">"&gt;&lt;p&gt;Do &lt;em&gt;not&lt;/em&gt; use the &lt;code class="</span><span class="n">language</span><span class="o">-</span><span class="n">plaintext</span> <span class="n">highlighter</span><span class="o">-</span><span class="n">rouge</span><span class="s">"&gt;getString()&lt;/code&gt; or &lt;code class="</span><span class="n">language</span><span class="o">-</span><span class="n">plaintext</span> <span class="n">highlighter</span><span class="o">-</span><span class="n">rouge</span><span class="s">"&gt;getInt()&lt;/code&gt;; These methods do not have any setter methods, and they do &lt;em&gt;not&lt;/em&gt; access the same values as the &lt;code class="</span><span class="n">language</span><span class="o">-</span><span class="n">plaintext</span> <span class="n">highlighter</span><span class="o">-</span><span class="n">rouge</span><span class="s">"&gt;get()&lt;/code&gt; method (&lt;code class="</span><span class="n">language</span><span class="o">-</span><span class="n">plaintext</span> <span class="n">highlighter</span><span class="o">-</span><span class="n">rouge</span><span class="err">"</span><span class="o">&gt;</span><span class="n">get</span><span class="o">()&lt;/</span><span class="n">code</span><span class="o">&gt;</span> <span class="n">actually</span> <span class="n">prefixes</span> <span class="n">the</span> <span class="n">keys</span> <span class="n">with</span> <span class="n">a</span> <span class="n">dot</span><span class="o">)!&lt;/</span><span class="n">p</span><span class="o">&gt;</span> <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span> <span class="o">&lt;/</span><span class="n">div</span><span class="o">&gt;</span> </code></pre></div></div> <h2 id="how-to-turn-a-number-into-a-string-using-a-given-number-of-decimal-places">How to turn a number into a string, using a given number of decimal places</h2> <p>Use the <code class="language-plaintext highlighter-rouge">d2s()</code> method of the <code class="language-plaintext highlighter-rouge">ij.IJ</code> class:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">String</span> <span class="n">message</span> <span class="o">=</span> <span class="s">"The current temperature is "</span> <span class="o">+</span> <span class="no">IJ</span><span class="o">.</span><span class="na">d2s</span><span class="o">(</span><span class="n">degrees</span><span class="o">,</span> <span class="mi">1</span><span class="o">)</span> <span class="o">+</span> <span class="s">"° Celsius"</span><span class="o">;</span> </code></pre></div></div> <h2 id="how-to-abort-a-plugin-completely">How to abort a plugin completely</h2> <p>Sometimes, you want to abort a plugin without catching an exception at the highest level(s), without having ImageJ show an exception window. You can do that:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">throw</span> <span class="k">new</span> <span class="nc">RuntimeException</span><span class="o">(</span><span class="nc">Macro</span><span class="o">.</span><span class="na">MACRO_CANCELED</span><span class="o">);</span> </code></pre></div></div> <p>The special message <em>Macro.MACRO_CANCELED</em> will tell ImageJ not to show the exception message and stack trace in a text window.</p> <h2 id="interact-with-the-roi-manager">Interact with the ROI manager</h2> <p>To add ROIs to the ROI manager, do something like this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">RoiManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">RoiManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">manager</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="n">manager</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">RoiManager</span><span class="o">();</span> <span class="n">manager</span><span class="o">.</span><span class="na">addRoi</span><span class="o">(</span><span class="n">roi</span><span class="o">);</span> </code></pre></div></div> <p>If you want to add the ROI with a slice label, you have to jump through a hoop:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="n">currentSlice</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="na">getCurrentSlice</span><span class="o">();</span> <span class="nc">RoiManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">RoiManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">manager</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="n">manager</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">RoiManager</span><span class="o">();</span> <span class="c1">// the first slice is 1 (not 0)</span> <span class="n">image</span><span class="o">.</span><span class="na">setSliceWithoutUpdate</span><span class="o">(</span><span class="n">slice</span><span class="o">);</span> <span class="n">manager</span><span class="o">.</span><span class="na">add</span><span class="o">(</span><span class="n">image</span><span class="o">,</span> <span class="n">rois</span><span class="o">[</span><span class="n">i</span><span class="o">],</span> <span class="n">slice</span><span class="o">);</span> <span class="n">image</span><span class="o">.</span><span class="na">setSlice</span><span class="o">(</span><span class="n">currentSlice</span><span class="o">);</span> </code></pre></div></div> <p>To retrieve all ROIs from the ROI manager, do this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">RoiManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">RoiManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">manager</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;</span> <span class="n">table</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;)</span><span class="n">manager</span><span class="o">.</span><span class="na">getROIs</span><span class="o">();</span> <span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">label</span> <span class="o">:</span> <span class="n">table</span><span class="o">.</span><span class="na">keySet</span><span class="o">())</span> <span class="o">{</span> <span class="kt">int</span> <span class="n">slice</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getSliceNumber</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="nc">Roi</span> <span class="n">roi</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="o">...</span> <span class="o">&lt;</span><span class="k">do</span> <span class="n">something</span> <span class="n">with</span> <span class="n">the</span> <span class="no">ROI</span> <span class="n">and</span> <span class="n">the</span> <span class="n">slice</span><span class="o">&gt;</span> <span class="o">...</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p>If you need to preserve the order of the ROIs in the ROI manager, unfortunately you’ll have to access the AWT listbox:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.awt.List</span><span class="o">;</span> <span class="o">...</span> <span class="nc">RoiManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">RoiManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">manager</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="nc">List</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getList</span><span class="o">();</span> <span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;</span> <span class="n">table</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;)</span><span class="n">manager</span><span class="o">.</span><span class="na">getROIs</span><span class="o">();</span> <span class="k">for</span> <span class="o">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">labels</span><span class="o">.</span><span class="na">getItemCount</span><span class="o">();</span> <span class="n">i</span><span class="o">++)</span> <span class="o">{</span> <span class="nc">String</span> <span class="n">label</span> <span class="o">=</span> <span class="n">labels</span><span class="o">.</span><span class="na">getItem</span><span class="o">(</span><span class="n">i</span><span class="o">);</span> <span class="kt">int</span> <span class="n">slice</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getSliceNumber</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="nc">Roi</span> <span class="n">roi</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="o">...</span> <span class="o">&lt;</span><span class="k">do</span> <span class="n">something</span> <span class="n">with</span> <span class="n">the</span> <span class="no">ROI</span> <span class="n">and</span> <span class="n">the</span> <span class="n">slice</span><span class="o">&gt;</span> <span class="o">...</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <p>To get just the selected ROIs, use code similar to this:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">java.awt.List</span><span class="o">;</span> <span class="o">...</span> <span class="nc">RoiManager</span> <span class="n">manager</span> <span class="o">=</span> <span class="nc">RoiManager</span><span class="o">.</span><span class="na">getInstance</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">manager</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="nc">String</span><span class="o">[]</span> <span class="n">labels</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getList</span><span class="o">().</span><span class="na">getSelectedItems</span><span class="o">();</span> <span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;</span> <span class="n">table</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Hashtable</span><span class="o">&lt;</span><span class="nc">String</span><span class="o">,</span> <span class="nc">Roi</span><span class="o">&gt;)</span><span class="n">manager</span><span class="o">.</span><span class="na">getROIs</span><span class="o">();</span> <span class="k">for</span> <span class="o">(</span><span class="nc">String</span> <span class="n">label</span> <span class="o">:</span> <span class="n">labels</span><span class="o">)</span> <span class="o">{</span> <span class="kt">int</span> <span class="n">slice</span> <span class="o">=</span> <span class="n">manager</span><span class="o">.</span><span class="na">getSliceNumber</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="nc">Roi</span> <span class="n">roi</span> <span class="o">=</span> <span class="n">table</span><span class="o">.</span><span class="na">get</span><span class="o">(</span><span class="n">label</span><span class="o">);</span> <span class="o">...</span> <span class="o">&lt;</span><span class="k">do</span> <span class="n">something</span> <span class="n">with</span> <span class="n">the</span> <span class="no">ROI</span> <span class="n">and</span> <span class="n">the</span> <span class="n">slice</span><span class="o">&gt;</span> <span class="o">...</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <h2 id="show-a-results-table">Show a results table</h2> <p>First you need to get the results table instance (or create one):</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">ResultsTable</span> <span class="n">rt</span> <span class="o">=</span> <span class="nc">Analyzer</span><span class="o">.</span><span class="na">getResultsTable</span><span class="o">();</span> <span class="k">if</span> <span class="o">(</span><span class="n">rt</span> <span class="o">==</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">rt</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">ResultsTable</span><span class="o">();</span> <span class="nc">Analyzer</span><span class="o">.</span><span class="na">setResultsTable</span><span class="o">(</span><span class="n">rt</span><span class="o">);</span> <span class="o">}</span> </code></pre></div></div> <p>Then you can add a new row:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rt</span><span class="o">.</span><span class="na">incrementCounter</span><span class="o">();</span> </code></pre></div></div> <p>… and add entries by column label:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rt</span><span class="o">.</span><span class="na">addValue</span><span class="o">(</span><span class="s">"slice"</span><span class="o">,</span> <span class="n">slice</span><span class="o">);</span> <span class="n">rt</span><span class="o">.</span><span class="na">addValue</span><span class="o">(</span><span class="s">"bratwurst"</span><span class="o">,</span> <span class="o">-</span><span class="mi">1</span><span class="o">);</span> </code></pre></div></div> <p><strong>Finally</strong> make sure that the result table is displayed/updated:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">rt</span><span class="o">.</span><span class="na">show</span><span class="o">(</span><span class="s">"Results"</span><span class="o">);</span> </code></pre></div></div> <h2 id="how-to-find-equivalent-api-commands-between-imagej-1x-and-imagej2">How to find equivalent API commands between ImageJ 1.x and ImageJ2?</h2> <p><a href="/develop/ij1-ij2-cheat-sheet">ImageJ1-ImageJ2 cheat sheet</a> is available.</p> <h1 id="tips-for-graphical-user-interface-gui-programming">Tips for Graphical User Interface (GUI) programming</h1> <h2 id="programming-with-swing-components">Programming with Swing components</h2> <p>When programming with Swing, beware that Swing is not thread safe. Swing’s golden rule states that:</p> <p><em>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.</em></p> <p>When has a Swing component been realized? When it is visible inside Window or <em>JFrame</em> that got a call to <code class="language-plaintext highlighter-rouge">setVisible(true)</code>. This implies that its <code class="language-plaintext highlighter-rouge">paint(Graphics)</code> method has been called or will be called soon.</p> <p>These are the methods that can realize a component, or rather, methods called on a <em>Window</em> or <em>Frame</em> or <em>JFrame</em> that will realize all its children components:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">setVisible</span><span class="o">(</span><span class="kc">true</span><span class="o">)</span> <span class="n">show</span><span class="o">()</span> <span class="n">pack</span><span class="o">()</span> <span class="c1">// this might surprise you</span> </code></pre></div></div> <p>There is a class which helps you with all this: <a href="http://download.oracle.com/javase/6/docs/api/javax/swing/SwingUtilities.html">SwingUtilities</a>. Example: to call <code class="language-plaintext highlighter-rouge">pack()</code> from within the constructor (which might or might not be called from the Event Dispatch Thread):</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="o">(</span><span class="nc">SwingUtilities</span><span class="o">.</span><span class="na">isEventDispatchThread</span><span class="o">())</span> <span class="n">pack</span><span class="o">();</span> <span class="k">else</span> <span class="k">try</span> <span class="o">{</span> <span class="nc">SwingUtilities</span><span class="o">.</span><span class="na">invokeAndWait</span><span class="o">(</span><span class="k">new</span> <span class="nc">Runnable</span><span class="o">()</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">run</span><span class="o">()</span> <span class="o">{</span> <span class="n">pack</span><span class="o">();</span> <span class="o">}});</span> <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Exception</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> <span class="cm">/* ignore */</span> <span class="o">}</span> </code></pre></div></div> <p>Information extracted from the <a href="http://web.archive.org/web/20120801194837/http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html">Swing guide</a> (now only available from via web.archive.org as Oracle removed the original docs), additional information can be found in the <a href="http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html">Concurrency in Swing</a> lesson of <em>The Java Tutorials</em>.</p> <h1 id="arcane-quirks">Arcane Quirks</h1> <h2 id="softreference-and-outofmemoryerror">SoftReference and OutOfMemoryError</h2> <p>We have recently learned an interesting fact about Java’s <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html">SoftReference</a> and the potential occurence of an <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html">OutOfMemoryError</a>. The result first: An <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html">OutOfMemoryError</a> may be thrown in a situation where <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html">SoftReferences</a> can be released after which enough memory would be available. The reason is that normal garbage collection happens in an independent thread and does not halt other threads when they allocate memory. Only an explicit <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/System.html#gc%28%29">System.gc()</a> waits until the memory is freed . The consequence is that whenever you allocate memory then you should do that with the following clause:</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="nc">MyObject</span> <span class="n">o</span><span class="o">;</span> <span class="k">try</span> <span class="o">{</span> <span class="n">o</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyObject</span><span class="o">();</span> <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">OutOfMemoryError</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> <span class="nc">System</span><span class="o">.</span><span class="na">gc</span><span class="o">();</span> <span class="n">o</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">MyObject</span><span class="o">();</span> <span class="o">}</span> </code></pre></div></div> <p>We found this by implementing a simple cache using a <a href="http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html">HashMap</a> of <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html">SoftReferences</a> to an object that on finalize removes the corresponding key in the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html">HashMap</a>. That cache is used to store image tiles for an <a href="/libs/imglib2">ImgLib2</a> backend that uses a <a href="http://fly.mpi-cbg.de/~saalfeld/catmaid/">CATMAID</a> stack (<a href="https://github.com/imglib/imglib/blob/9f38afca3f0a4aa7b3ddc77160430a710a20501a/imglib2/tests/src/test/java/catmaid/CATMAIDRandomAccessibleInterval.java">GitHub</a>). It turned out that the painter thread in an interactive viewer was fetching new tiles quicker than the garbage collector would finalize <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ref/SoftReference.html">SoftReferences</a> and stopped with an <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/OutOfMemoryError.html">OutOfMemoryError</a>. We could solve that with the the above construct.</p> </div> </div> </section> <!-- Footer --> <section id="footer"> <ul class="icons"> <li><a href="https://forum.image.sc/tag/imagej" class="icon alt"><img src="/media/icons/image-sc.png" width="24" style="vertical-align: middle; margin-top: -10px"><span class="label">Forum</span></a></li> <li><a href="https://twitter.com/hashtag/ImageJ" class="icon brands alt fa-twitter"><span class="label">Twitter</span></a></li> <li><a href="https://github.com/imagej" class="icon brands alt fa-github"><span class="label">GitHub</span></a></li> </ul> <ul class="copyright"> <li>Design: <a href="http://html5up.net">HTML5 UP</a></li> </ul> </section> <!-- Hamburger menu --> <nav role="navigation"> <div id="ham-toggle"> <input type="checkbox" /> <span></span> <!-- top bun --> <span></span> <!-- hamburger --> <span></span> <!-- bottom bun --> <ul id="ham-menu"> <div class="menu"><h3>ImageJ Docs</h3> <ul> <li><a href="/downloads">Download</a></li> <li><details><summary>Learn</summary><ul> <li><details><summary><a href="/learn">ImageJ Basics</a></summary><ul> <li><a href="/tutorials">Tutorials</a></li> <li><a href="/learn/user-guides">User Guides</a></li> <li><a href="/learn/keyboard-shortcuts">Keyboard Shortcuts</a></li> <li><a href="/learn/tips-and-tricks">Tips and Tricks</a></li> <li><a href="/learn/troubleshooting">Troubleshooting</a></li> <li><a href="/learn/faq">Frequently Asked Questions</a></li> <li><details><summary><a href="/platforms">Supported Platforms</a></summary><ul> <li><a href="/platforms/windows">Windows</a></li> <li><a href="/platforms/macos">MacOS</a></li> <li><a href="/platforms/linux">Linux</a></li> <li><a href="/platforms/pi">Raspberry Pi</a></li> <li><a href="/platforms/android">Android</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/Supported Platforms --> <li><details><summary><a href="/formats">File Formats</a></summary><ul> <li><a href="/formats/bio-formats">Bio-Formats</a></li> <li><a href="/formats/video">Video formats</a></li> <li><a href="/formats/quicktime">QuickTime</a></li> <li><a href="/formats/tiff">TIFF</a></li> <li><a href="/formats/pdf">PDF</a></li> <li><a href="/formats/dicom">DICOM</a></li> <li><a href="/formats/lsm">Zeiss LSM</a></li> <li><a href="/formats/olympus">Olympus VSI</a></li> <li><a href="/formats/lurawave">Opera Flex</a></li> <li><a href="/formats/fib-sem">FIB-SEM</a></li> </ul></details></li> <!-- Learn/ImageJ Basics/File Formats --> </ul></details></li> <!-- Learn/ImageJ --> <li><details><summary><a href="/imaging">Scientific Imaging</a></summary><ul> <li><a href="/imaging/principles">Principles of Scientific Imaging</a></li> <li><a href="/imaging/annotating-images">Annotating Images</a></li> <li><a href="/imaging/colocalization-analysis">Colocalization</a></li> <li><a href="/imaging/color-image-processing">Color Image Processing</a></li> <li><a href="/imaging/deconvolution">Deconvolution</a></li> <li><a href="/imaging/image-intensity-processing">Image Intensity Processing</a></li> <li><a href="/imaging/particle-analysis">Particle Analysis</a></li> <li><a href="/imaging/registration">Registration</a></li> <li><a href="/imaging/segmentation">Segmentation</a></li> <li><a href="/imaging/stack-slice-manipulations">Stack-slice Manipulations</a></li> <li><a href="/imaging/t-functions">T-functions</a></li> <li><a href="/imaging/tracking">Tracking</a></li> <li><a href="/imaging/visualization">Visualization</a></li> <li><a href="/imaging/z-functions">Z-functions</a></li> </ul></details></li> <!-- Learn/Scientific Imaging --> </ul></details></li> <!-- Learn --> <li><details open><summary><a href="/plugins">Extend</a></summary><ul> <li><a href="/list-of-extensions">List of Extensions</a></li> <li><details><summary><a href="/update-sites">Update Sites</a></summary><ul> <li><a href="/list-of-update-sites">List of Update Sites</a></li> <li><a href="/update-sites/following">Following an Update Site</a></li> <li><a href="/update-sites/setup">Creating an Update Site</a></li> <li><a href="/update-sites/tos">Terms of Service</a></li> <li><a href="/update-sites/automatic-uploads">Automatic Upload</a></li> <li><a href="/update-sites/core-uploads">Uploading to Core Sites</a></li> <li><a href="/update-sites/faq">Update Sites FAQ</a></li> <li><a href="/update-sites/stats">Statistics</a></li> </ul></details></li> <!-- Extend/Update Sites --> <li><details><summary><a href="/scripting">Scripting</a></summary><ul> <li><a href="/scripting/basics">Scripting Basics</a></li> <li><a href="/scripting/script-editor">Script Editor</a></li> <li><a href="/scripting/parameters">Parameters</a></li> <li><a href="/scripting/user-input">User Input</a></li> <li><a href="/scripting/auto-imports">Auto Import</a></li> <li><a href="/scripting/templates">Templates</a></li> <li><a href="/scripting/batch">Batch Processing</a></li> <li><a href="/scripting/headless">Running Headlessly</a></li> <li><a href="/scripting/comparisons">Scripting Comparisons</a></li> <li><a href="/scripting/toolbox">Toolbox</a></li> <li><details><summary>Languages</summary><ul> <li><a href="/scripting/beanshell">BeanShell Scripting</a></li> <li><a href="/scripting/groovy">Groovy Scripting</a></li> <li><a href="/scripting/macro">ImageJ Macro</a></li> <li><a href="/scripting/javascript">JavaScript</a></li> <li><a href="/scripting/clojure">Lisp (Clojure)</a></li> <li><a href="/scripting/matlab">MATLAB</a></li> <li><a href="/scripting/jython">Python (Jython)</a></li> <li><a href="/scripting/python">Python (native)</a></li> <li><a href="/scripting/renjin">R (Renjin)</a></li> <li><a href="/scripting/jruby">Ruby (JRuby)</a></li> <li><a href="/scripting/scala">Scala Scripting</a></li> </ul></details></li> <!-- Extend/Scripting/Languages --> </ul></details></li> <!-- Extend/Scripting --> <li><details open><summary><a href="/develop">Development</a></summary><ul> <li><a href="/develop/philosophy">Philosophy</a></li> <li><a href="/develop/architecture">Architecture</a></li> <li><a href="/develop/source">Source code</a></li> <li><a href="/develop/project-management">Project management</a></li> <li><a href="/develop/coding-style">Coding style</a></li> <li><a href="/develop/javadoc">Using Javadoc</a></li> <li><a href="/develop/debugging">Debugging</a></li> <li><a href="/develop/wish-list">Wish list</a></li> <li><details><summary>Tools</summary><ul> <li><a href="/develop/github">GitHub</a></li> <li><a href="/develop/maven">Maven</a></li> <li><a href="/develop/ci">CI/CD</a></li> <li><a href="/develop/dotfiles">Dotfiles</a></li> <li><details><summary><a href="/develop/ides">IDEs</a></summary><ul> <li><a href="/develop/eclipse">Eclipse</a></li> <li><a href="/develop/netbeans">NetBeans</a></li> <li><a href="/develop/intellij">IntelliJ IDEA</a></li> <li><a href="/develop/command-line">Command Line</a></li> </ul></details></li> </ul></details></li> <!-- Extend/Development/Tools --> <li><details open><summary>Guides</summary><ul> <li><a href="/develop/plugins">Writing plugins</a></li> <li><a href="/develop/improving-the-code">Contributing to a plugin</a></li> <li><a href="/develop/releasing">Development lifecycle</a></li> <li><a href="/develop/building-a-pom">Building a POM</a></li> <li><a href="/develop/debugging-exercises">Hands-on debugging</a></li> <li><a href="/develop/writing-ops">Adding new ops</a></li> <li><a href="/develop/formats">Adding new formats</a></li> <li><a href="/develop/native-libraries">Using native libraries</a></li> <li><a class="current-page">Tips for developers</a></li> <li><a href="/develop/cpp-tips">Tips for C++ developers</a></li> <li><a href="/develop/ij1-plugins">ImageJ 1.x plugins</a></li> <li><a href="/develop/versioning">Versioning</a></li> <li><a href="/develop/logging">Logging</a></li> <li><a href="/develop/uber-jars">Uber-JARs</a></li> </ul></details></li> <!-- Extend/Development/Guides --> <li><details><summary><a href="/develop/git">Git</a></summary><ul> <li><a href="/develop/git/eclipse">Git in Eclipse (EGit)</a></li> <li><a href="/develop/git/mini-howto">Git mini howto</a></li> <li><a href="/develop/git/workshop">Git workshop</a></li> <li><a href="/develop/git/conflicts">Git conflicts</a></li> <li><a href="/develop/git/topic-branches">Git topic branches</a></li> <li><a href="/develop/git/notes">Git notes</a></li> <li><a href="/develop/git/reflogs">Git reflogs</a></li> <li><a href="/develop/git/submodules">Git submodules</a></li> <li><a href="/develop/git/pinpoint-regressions">How to pinpoint regressions</a></li> <li><a href="/develop/git/publish-a-repository">How to publish a git repository</a></li> <li><a href="/develop/git/extract-a-subproject">How to extract a subproject</a></li> </ul></details></li> <!-- Extend/Development/Git --> </ul></details></li> <!-- Extend/Development --> </ul></details></li> <!-- Extend --> <li><details><summary><a href="/contribute">Contribute</a></summary><ul> <li><a href="/contribute/citing">Citing</a></li> <li><a href="/people">Contributors</a></li> <li><a href="/orgs">Organizations</a></li> <li><a href="/contribute/governance">Governance</a></li> <li><a href="/contribute/funding">Funding</a></li> <li><a href="/contribute/fiji">Contributing to Fiji</a></li> <li><details><summary><a href="/licensing">Licensing</a></summary><ul> <li><details><summary><a href="/licensing/open-source">Open Source</a></summary><ul> <li><a href="/licensing/apache">Apache</a></li> <li><a href="/licensing/bsd">BSD</a></li> <li><a href="/licensing/epl">EPL</a></li> <li><a href="/licensing/gpl">GPL</a></li> <li><a href="/licensing/lgpl">LGPL</a></li> <li><a href="/licensing/mit">MIT</a></li> <li><a href="/licensing/public-domain">Public domain</a></li> <li><a href="/licensing/big">BIG</a></li> </ul></details></li> <!-- Contribute/Licensing/Open Source --> <li><a href="/licensing/closed-source">Proprietary</a></li> </ul></details></li> <!-- Contribute/Licensing --> <li><details><summary><a href="/editing">Editing the Wiki</a></summary><ul> <li><a href="/editing/advanced">Advanced Editing</a></li> <li><a href="/editing/buttons">Buttons</a></li> <li><a href="/editing/citations">Citations</a></li> <li><a href="/editing/code">Source Code</a></li> <li><a href="/editing/debugging">Debugging</a></li> <li><a href="/editing/headers">Headers</a></li> <li><a href="/editing/icons">Icons</a></li> <li><a href="/editing/images">Images</a></li> <li><a href="/editing/keys">Keyboard Shortcuts</a></li> <li><a href="/editing/linking">Linking</a></li> <li><a href="/editing/math">Math Expressions</a></li> <li><a href="/editing/menu-paths">Menu Paths</a></li> <li><a href="/editing/navigation">Navigation</a></li> <li><a href="/editing/notices">Notices</a></li> <li><a href="/editing/people">People</a></li> <li><a href="/editing/pitfalls">Pitfalls</a></li> <li><a href="/editing/quizzes">Quizzes</a></li> <li><a href="/editing/statbox">Statbox</a></li> <li><a href="/editing/symbols">Symbols</a></li> <li><a href="/editing/tables">Tables</a></li> <li><a href="/editing/timelines">Timelines</a></li> <li><a href="/editing/tooltips">Tooltips</a></li> <li><a href="/editing/videos">Videos</a></li> <li><a href="/editing/whitespace">Whitespace</a></li> </ul></details></li> <!-- Contribute/Editing the Wiki --> </ul></details></li> <!-- Contribute --> <li><details><summary><a href="/discuss">Discuss</a></summary><ul> <li><a href="/discuss/bugs">Reporting Issues</a></li> <li><a href="/discuss/mailing-lists">Mailing Lists</a></li> <li><a href="/discuss/chat">Chat</a></li> </ul></details></li> <!-- Discuss --> <li><details><summary>Explore</summary><ul> <li><a href="/news">News</a></li> <li><details><summary><a href="/events">Events</a></summary><ul> <li><a href="/events/presentations">Presentations</a></li> <li><a href="/events/conferences">Conferences</a></li> <li><a href="/events/hackathons">Hackathons</a></li> <li><a href="/events">More...</a></li> </ul></details></li> <!-- Discuss/Events --> <li><details><summary><a href="/libs">Libraries</a></summary><ul> <li><a href="/libs/imagej-ops">ImageJ Ops</a></li> <li><a href="/libs/imagej-common">ImageJ Common</a></li> <li><a href="/libs/imagej-legacy">ImageJ Legacy</a></li> <li><a href="/libs/scijava">SciJava</a></li> <li><a href="/libs/scifio">SCIFIO</a></li> <li><details><summary><a href="/libs/imglib2">ImgLib2</a></summary><ul> <li><a href="/libs/imglib2/getting-started">Getting Started</a></li> <li><a href="/libs/imglib2/accessors">Accessors</a></li> <li><a href="/libs/imglib2/accessibles">Accessibles</a></li> <li><a href="/libs/imglib2/examples">Examples</a></li> <li><a href="/libs/imglib2/workshop-introductory">Introductory Workshop</a></li> <li><a href="/libs/imglib2/workshop-advanced">Advanced Workshop</a></li> <li><a href="/libs/imglib2/matlab">ImgLib2 images in MATLAB</a></li> <li><a href="/libs/imglib2/benchmarks">Benchmarks</a></li> <li><a href="/libs/imglib2/faq">FAQ</a></li> <li><a href="/libs/imglib2/developing">Developing ImgLib2</a></li> <li><a href="/libs/imglib2/discussion">ImgLib2 Discussion</a></li> </ul></details></li> <!-- Explore/Libraries/ImgLib2 --> <li><a href="/libs">More...</a></li> </ul></details></li> <!-- Explore/Libraries --> <li><details><summary><a href="/software">Software</a></summary><ul> <li><a href="/software/nih-image">NIH Image</a></li> <li><a href="/software/imagej">ImageJ</a></li> <li><a href="/software/imagej2">ImageJ2</a></li> <li><a href="/software/fiji">Fiji</a></li> <li><a href="/software">More...</a></li> </ul></details></li> <!-- Explore/Software --> </ul></details></li> <!-- Explore --> </ul> </div> </ul> </div> </nav> <div id="dock-overlay-left" class="dock-overlay" data-dock-target="left-column"></div> <div id="dock-overlay-right" class="dock-overlay" data-dock-target="right-column"></div> <!-- Search results --> <div id="search-results"> <div id="search-hits"></div> <div id="pagination"></div> </div> <!-- Scripts --> <!-- Libraries --> <script src="/assets/js/jquery.min.js"></script> <script src="/assets/js/jquery.scrolly.min.js"></script> <script src="/assets/js/browser.min.js"></script> <script src="/assets/js/breakpoints.min.js"></script> <script src="/assets/js/util.js"></script> <script src="/assets/js/jquery.toc.js"></script> <script src="/assets/js/lightbox.min.js"></script> <!-- Extensions --> <!-- Site code --> <script src="/assets/js/main.js"></script> <script src="/assets/js/dock.js"></script> <script src="/assets/js/code.js"></script> <!-- Anchors --> <script src="https://cdn.jsdelivr.net/npm/anchor-js/anchor.min.js"></script> <script>anchors.add('#page h1, #page h2, #page h3, #page h4, #page h5, #page h6');</script> <!-- Citations --> <script src="https://cdn.jsdelivr.net/npm/citation-js@0.4.0-9"></script> <script src="/assets/js/cite.js"></script> <!-- Search --> <script src="https://cdn.jsdelivr.net/npm/algoliasearch@4.13.0/dist/algoliasearch-lite.umd.js"></script> <script src="https://cdn.jsdelivr.net/npm/instantsearch.js@4.40.3/dist/instantsearch.production.min.js"></script> <script src="/assets/js/search.js"></script> <script src="/assets/js/search-tweaks.js"></script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10