Hi Kenneth,
to me, the Roi.endPaste() issue is not a race condition.
A race condition means that one thread has not finished while another
thread is still working, and the first thread wands some result of the
other thread.
Race conditions can be mitigated by some delay. This is not the case for
Roi.endPaste().
--- Concerning problems similar to endPaste that can occur when
programming in Java, not in the GUI, I am aware of only one:
In the GUI, in almost all cases an undo buffer is created before a
command is executed, so you can undo it with either Edit>Undo or
Edit>Selection>Restore Selection.
Exception: Usually, there is no undo buffer for stack operations.
When programing in Java and *not* using IJ.run() commands that mimick
the GUI-induced operations, in many cases you have to care about this
yourself, either calling the Undo class for modification or with
ImagePlus.saveRoi() for Rois.
--- Concerning true race conditions:
Almost all race conditions are related to the fact that showing windows
on the screen is asynchronous in Java. (This avoids that a slow window
manager of the operating system slows down everything.)
The most common case is that a newly created image will appear on the
screen some time after you call ImagePlus.show(). It won't be the
foreground window (and active image) immediately, but later.
ImageJ cannot determine why that image became the foreground window,
whether by the user clicking on it or because it was newly displayed.
This means that the newly created window can become the active window
(and the active image) although if you have in the meanwhile selected
another image.
To avoid such problems, ImagePlus has a waitTillActivated() method,
which should be called after ImagePlus.show.
[Note that waitTillActivated does not work and cannot work in the
EventQueue, but one should not call potentially slow operations in the
EventQueue anyhow.]
To avoid using the wrong image, it is also a good practice to use
IJ.run(ImagePlus imp, String command, String options)
and not just IJ.run(String command, String options), which takes the
currently active image, whatever it might be.
Michael
________________________________________________________________
On 22.01.25 16:15, Kenneth R Sloan wrote:
I’m curious - how many other ImageJ operations have methods similar to
“EndPaste” which make sure that the operation has finished before
proceeding?
Is there a general “best practice” to avoid race conditions (other than
waiting - which only improves things without providing a guarantee)?
Is there information on which methods return control to a calling Java
program before the operation is complete?
—-
Kenneth Sloan
(von meinem iPhone13 gesendet)
On Wed, Jan 22, 2025 at 09:27 Michael Schmid <[email protected]>
wrote:
Hi William,
after a paste operation, you should always have an endPaste. Before
that, the paste operation is not really done, e.g. the user can still
move the pasted image around by dragging it with the mouse or use
Edit>Paste Control... [1] to change the paste mode.
Roi roi = getRoi();
if (roi!=null) roi.endPaste();
Before endPaste, ImageProcessor.rotate will work on the previous image
contents (the one before pasting).
A bit of background information:
Most ImageJ processing commands are implemented as a PlugInFilters.
Before running a PlugInFilter, ImageJ does an endPaste. Thus, if you use
IJ.run(newImp, "Rotate... ", "angle=15 interpolation=Bilinear");
this problem won't occur.
Michael
[1] https://imagej.net/ij/docs/guide/146-27.html#sub:Paste-Control...
________________________________________________________________
On 22.01.25 13:39, William Rust wrote:
I got it working 2 minutes after I made the post. Clearing the ROI fixed
it
although you are probably right. I also started remembering that the ip
is
immutable in the imp so I started updating that as well. In any case,
it's
working now and I thank you for your help.
wjr
On Wed, Jan 22, 2025 at 07:05 William Rust <[email protected]> wrote:
I'm writing code in java. What I am trying to do is take an image with
20
wheat kernels in a petri dish and put each kernel in its own image with
the
kernel rotated so all kernels are roughly vertical. Here's the code
snippet
where I am doing it.
ImageProcessor newIp = new ColorProcessor(300, 300);
ImagePlus newImp = new ImagePlus("sub " + idx, newIp);
newIp.setColor(background);
newIp.fill();
imp.copy();
newImp.paste();
newImp.getProcessor().rotate(angle[idx]);
newImp.updateAndDraw();
newImp.show();
Previously, I've cut the subimage out of the original image using the
bounding box from analyze particles. The weirdness occurs somewhere
between
the paste and the rotate. The pasting works whether I do the rotate or
not.
But when I paste, the rotate does not work. And, if I don't paste, the
rotate does work (I can tell this because the background is tilted after
a
rotate with no paste but not with rotate and paste). This snippet shows
one
of the things that I've tried, the updateAndDraw(), but nothing has
worked.
Any ideas on what I'm doing wrong?
Thanks,
wjr.
--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html
--
ImageJ mailing list: http://imagej.nih.gov/ij/list.html