I have a plugin which displays an image, removes IJ.instance Key and Image Listeners, adds itself as Key and ImageListener, and handles keypresses for the keys 1-6.
It works perfectly on my machine (a mac, latest OS) - but fails on someone elses - INTERMITTENTLY. When it fails, the plugin reports removing and adding the appropriate listeners...and then never reports seeing ANY keypress. (keyPressed() is never called). I followed the template in keyListener.java (I think that's the right name). There is a requestFocus() in what I think is the right place, and I've asked the "client" to be sure the image window is on top and "selected". No joy. I'm stumped - does anyone have any experience with similar problems? Any suggestions on how to proceed? Recall that I can't reproduce the problem on my machine. My "client" reports that the plugin sometimes works - perhaps several times in a row - and then fails. Once it starts to fail, even restarting FIJI does not revive it. I'm guessing (but have not asked) that it requires a reboot to fix. Any clues? -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Dear Kenneth,
I've run in a similar problem with a python Macro I wrote for TrakEM2 with the precious help of Albert Cardona. http://imagej.1557.x6.nabble.com/Adding-keyboard-shortcut-to-toggle-visibility-of-patches-in-TrakEM2-td5016099.html This macro sometimes behave exactly as you described, stopping working randomly. In our case however, re-running the macro is sufficient to make it work again. Back in 2016 we also had to open a new display, the instance to which the KeyListener is bound, but this magically resolved at some point. Moreover, lately this strange behaviour is very rare and we are indeed successfully using it. Here the final code, multiple keys are specified with subsequent elif from java.awt.event import KeyEvent, KeyAdapter from ini.trakem2.display import Display, Patch shortCut1="GFP" class MyKeyListener(KeyAdapter): def keyPressed(self, event): keyCode = event.getKeyCode() if KeyEvent.VK_1 == keyCode: for layer in Display.getFront().getLayerSet().getLayers(): patches = layer.getDisplayables(Patch) for patch in patches: if shortCut1 in patch.title: if patch.visible == True: patch.visible = False else: patch.visible = True Display.getFront().getCanvas().addKeyListener(MyKeyListener()) Hope this helps Federico Il giorno mer 18 mar 2020 alle ore 02:20 Kenneth Sloan < [hidden email]> ha scritto: > I have a plugin which displays an image, removes IJ.instance Key and Image > Listeners, adds itself as Key and ImageListener, and handles keypresses for > the keys 1-6. > > It works perfectly on my machine (a mac, latest OS) - but fails on someone > elses - INTERMITTENTLY. > > When it fails, the plugin reports removing and adding the appropriate > listeners...and then never reports seeing ANY keypress. (keyPressed() is > never called). > > I followed the template in keyListener.java (I think that's the right > name). > > There is a requestFocus() in what I think is the right place, and I've > asked the "client" to be sure the image window is on top and "selected". > No joy. > > I'm stumped - does anyone have any experience with similar problems? Any > suggestions on how to proceed? Recall that I can't reproduce the problem > on my machine. My "client" reports that the plugin sometimes works - > perhaps several times in a row - and then fails. Once it starts to fail, > even restarting FIJI does not revive it. I'm guessing (but have not asked) > that it requires a reboot to fix. > > Any clues? > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- Federico Luzzati, PhD Assistant Professor University of Turin, Dept. LIfe Sciences and Systems Biology (DBIOS) Via Accademia Albertina, 13 - 10123 Torino - IT Researcher at Neuroscience Institute Cavalieri Ottolenghi (NICO) Regione Gonzole, 10 - 10043 Orbassano (To) - IT tel. +39-0116704683/ -6631 http://www.nico.ottolenghi.unito.it/index.php/it/adult-neurogenesis Sostieni con il tuo 5xmille il NICO e la ricerca sulle malattie neurodegenerative Firma nel riquadro "Finanziamento della ricerca scientifica e dell'Università" CF 97564560015 -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
This is a JAVA plugin. It's too big to post all of it - but here are what I think are the relevant parts. Again - it works perfectly on one machine - and fails intermittently on another.
Perhaps someone who has done this before can spot my error. I was following the template for keyListener on the imageJ site. public class AVL_Area_Fraction implements PlugIn, KeyListener, ImageListener { ... private boolean waitingForKey = false; private int keyCode; private char keyChar; private int modifiers; @Override public void keyTyped(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) {} @Override public void keyPressed(KeyEvent e) { IJ.log("keyPressed"); if(!waitingForKey) return; // ignore keyboard when we don't want a key keyCode = e.getKeyCode(); keyChar = e.getKeyChar(); modifiers = e.getModifiers(); IJ.log(" "+keyCode+" "+keyChar+" "+modifiers); waitingForKey = false; } @Override public void imageClosed(ImagePlus imp) { IJ.log("imageClosed"); if(null!=win) win.removeKeyListener(this); if(null!=canvas) canvas.removeKeyListener(this); ImagePlus.removeImageListener(this); IJ.log("removed Listeners"); } @Override public void imageOpened(ImagePlus imp){} @Override public void imageUpdated(ImagePlus imp){} @Override public void run(String arg0) { ... other setup // listen to keyboard - stop IJ from listening! win.removeKeyListener(IJ.getInstance()); canvas.removeKeyListener(IJ.getInstance()); IJ.log("removed IJ Listeners"); win.addKeyListener(this); canvas.addKeyListener(this); ImagePlus.addImageListener(this); IJ.log("added Listeners"); ... int category; try { win.requestFocus(); IJ.log("sampling..."); category = sampleAt(...); IJ.log("sampled"); } catch (Exception e) { throw new RuntimeException(programName+" interrupted"); } ... // done listening to the keyboard win.removeKeyListener(this); canvas.removeKeyListener(this); ImagePlus.removeImageListener(this); IJ.log("removed Listeners"); ... private int sampleAt(...) throws InterruptedException { ... while(true) { waitingForKey = true; while(waitingForKey) Thread.sleep(100); // key pressed! // keyCode, keyChar, and modifiers are current if(keyCode == KeyEvent.VK_SPACE) return -1; // DELETE does not work if(keyCode == KeyEvent.VK_ENTER) return -2; // no mas! int category = keyCode - KeyEvent.VK_1; // 1-based keys; 0-based category if(category < 0) continue; // try again! if(category >= choices.length) continue; // try again! return category; // good category! } } } Looking at this, I'm wondering if there might be a race condition between adding the Listeners and going into the busy wait for "waitingForKey" to become false. But...that doesn't look like an issue - so I'm just at a loss. When this fails, the log window shows ============================ removed IJ Listeners added Listeners sampling... ============================ So, it's clearly (?) stuck in the wait loop, and keyPressed is never called. If anyone is up for it, I'd be happy to send the entire plugin for testing. Again - works perfectly on one machine and fails intermittently on another. Both mac laptops - the failing one is older than the one that works. I think the "client" is currently testing on a 3rd laptop to see if the problem is specific to that one machine. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Kenneth,
a few thoughts: If you suspect a race condition between ImageListener and KeyListener, can you try with the ImageJ daily build? Since a few days, the ImageListener callbacks are in the EventQueue. KeyListener callbacks are in the EventQueue anyhow. So a race condition between these callbacks cannot happen with the daily build. By the way, after you are done, don't forget to register ImageJ as a KeyListener again. Instead of an endless loop for waiting, it would be nicer to use the Java 'wait' and 'notify' mechanism (both must be in 'synchronized' blocks). There is an example in the PlotWindow class: https://github.com/imagej/imagej1/blob/master/ij/gui/PlotWindow.java#L836 https://github.com/imagej/imagej1/blob/master/ij/gui/PlotWindow.java#L865 In your code with the endless loop, it would be better to declare 'waitingForKey' volatile or have an AtomicBoolean for it. Otherwise, if the threads running the keyListener callback (the EventQueue) and the one running the endless loop are on different CPU cores, the one running the event queue may have the "waitingForKey" variable in its own CPU cache and it may go undetected that another core modifies it. So the statement > waitingForKey = true; > while(waitingForKey) Thread.sleep(100); might actually behave like this: > while(true) Thread.sleep(100); If you use the synchronized notify/wait mechanism instead, there is no need for declaring variables as volatile because synchronized blocks also care about the cache problem. Michael ______________________________________________________________________ On 18/03/2020 2:17 pm, Kenneth Sloan wrote: > This is a JAVA plugin. It's too big to post all of it - but here are what I think are the relevant parts. Again - it works perfectly on one machine - and fails intermittently on another. > > Perhaps someone who has done this before can spot my error. I was following the template for keyListener on the imageJ site. > > > public class AVL_Area_Fraction implements PlugIn, KeyListener, ImageListener > { > ... > private boolean waitingForKey = false; > private int keyCode; > private char keyChar; > private int modifiers; > @Override > public void keyTyped(KeyEvent e) {} > @Override > public void keyReleased(KeyEvent e) {} > @Override > public void keyPressed(KeyEvent e) > { > IJ.log("keyPressed"); > if(!waitingForKey) return; // ignore keyboard when we don't want a key > keyCode = e.getKeyCode(); > keyChar = e.getKeyChar(); > modifiers = e.getModifiers(); > IJ.log(" "+keyCode+" "+keyChar+" "+modifiers); > waitingForKey = false; > } > > @Override > public void imageClosed(ImagePlus imp) > { > IJ.log("imageClosed"); > if(null!=win) win.removeKeyListener(this); > if(null!=canvas) canvas.removeKeyListener(this); > ImagePlus.removeImageListener(this); > IJ.log("removed Listeners"); > } > @Override > public void imageOpened(ImagePlus imp){} > @Override > public void imageUpdated(ImagePlus imp){} > @Override > public void run(String arg0) > { > ... other setup > // listen to keyboard - stop IJ from listening! > win.removeKeyListener(IJ.getInstance()); > canvas.removeKeyListener(IJ.getInstance()); > IJ.log("removed IJ Listeners"); > win.addKeyListener(this); > canvas.addKeyListener(this); > ImagePlus.addImageListener(this); > IJ.log("added Listeners"); > ... > > int category; > try > { > win.requestFocus(); > IJ.log("sampling..."); > category = sampleAt(...); > IJ.log("sampled"); > } > catch (Exception e) > { > throw new RuntimeException(programName+" interrupted"); > } > ... > // done listening to the keyboard > win.removeKeyListener(this); > canvas.removeKeyListener(this); > ImagePlus.removeImageListener(this); > IJ.log("removed Listeners"); > ... > > private int sampleAt(...) > throws InterruptedException > { > ... > while(true) > { > waitingForKey = true; > while(waitingForKey) Thread.sleep(100); > > // key pressed! > // keyCode, keyChar, and modifiers are current > if(keyCode == KeyEvent.VK_SPACE) return -1; // DELETE does not work > if(keyCode == KeyEvent.VK_ENTER) return -2; // no mas! > int category = keyCode - KeyEvent.VK_1; // 1-based keys; 0-based category > if(category < 0) continue; // try again! > if(category >= choices.length) continue; // try again! > return category; // good category! > } > } > } > > > > Looking at this, I'm wondering if there might be a race condition between adding the Listeners and going into the busy wait for "waitingForKey" to become false. But...that doesn't look like an issue - so I'm just at a loss. > > When this fails, the log window shows > > ============================ > removed IJ Listeners > added Listeners > sampling... > ============================ > > So, it's clearly (?) stuck in the wait loop, and keyPressed is never called. > > If anyone is up for it, I'd be happy to send the entire plugin for testing. > > Again - works perfectly on one machine and fails intermittently on another. Both mac laptops - the failing one is older than the one that works. I think the "client" is currently testing on a 3rd laptop to see if the problem is specific to that one machine. > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Michael-
Thanks - I was trying to keep it simple, and failed. I suspect that the multi-core issue is the correct answer. I'll work on it. Thank you for the prompt reply. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael Schmid
Thank you!
I made the following changes: ... @Override public void keyPressed(KeyEvent e) { IJ.log("keyPressed"); keyCode = e.getKeyCode(); keyChar = e.getKeyChar(); modifiers = e.getModifiers(); IJ.log(" "+keyCode+" "+keyChar+" "+modifiers); synchronized(this) { IJ.log("notifying"); notify(); IJ.log("notified"); } } ... while(true) { synchronized(this) { IJ.log("waiting..."); wait(); // keyPressed wakes us IJ.log("woken up!"); } // key pressed! ... and it's fine (on my machine...which is less than informative, but at least I didn't break anything). Shipping now for the "client" to test. Again - thank you for the prompt and useful reply. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
No joy. The improved(?) version exhibits the same problem. Now on two machines (but not yet on mine). The symptoms are that no KeyPresses are registered AT ALL. Note that there is a call to IJ.log at the start of keyPressed() - so this is not an issue with wait/notify. I'm glad I cleaned that up - but it wasn't the problem.
It appears as if the KeyListeners are not being registered. Is there a way to double check that a given class has been successfully registered as a KeyListener? It also occurs to me that there might be a race condition here: ipl.show(); win = ipl.getWindow(); canvas = win.getCanvas(); Is it possible that win and canvas may not yet be set, because ipl.show() takes some time to complete? Should I add something like "wait(1000)" after the ipl.show()"? Is there a direct way to check that ipl.show() has finished all of its work before proceeding? For example...will this help? ... ipl.show(); ImageWindow win = null; while(null == win) {win = ipl.getWindow();} ... -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Hi Kenneth,
getting KeyListeners: There is method KeyListener[] Component.getKeyListeners(). Canvases, Containers (Windows, Panels), and gui elements (checkboxes, text fields, ...) are java.awt.Components. ImagePlus.show() should wait until the window appears, unless you call it from the EventQueue (e.g. from any Listener). Then you will experience a 2 sec delay, which is its timeout for waiting (if the image has not appeared yet in 2 sec). If you want to create the ImagePlus from the EventQueue, start a new Thread that creates it. After spawning the thread, I think you need a loop with maybe 10 msec delay waiting until the ImagePlus is shown (e.g. check for imp.getWindow() being non-null and win.isVisible() being true). If it is possible that your plugin will ever run in a macro, make sure that it also works in batchmode where no window will be displayed. Michael _____________________________________________________________ On 18/03/2020 5:52 pm, Kenneth Sloan wrote: > No joy. The improved(?) version exhibits the same problem. Now on two machines (but not yet on mine). The symptoms are that no KeyPresses are registered AT ALL. Note that there is a call to IJ.log at the start of keyPressed() - so this is not an issue with wait/notify. I'm glad I cleaned that up - but it wasn't the problem. > > It appears as if the KeyListeners are not being registered. Is there a way to double check that a given class has been successfully registered as a KeyListener? > > It also occurs to me that there might be a race condition here: > > ipl.show(); > win = ipl.getWindow(); > canvas = win.getCanvas(); > > Is it possible that win and canvas may not yet be set, because ipl.show() takes some time to complete? Should I add something like "wait(1000)" after the ipl.show()"? Is there a direct way to check that ipl.show() has finished all of its work before proceeding? > > For example...will this help? > > ... > ipl.show(); > ImageWindow win = null; > while(null == win) {win = ipl.getWindow();} > ... > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
I have solved the potential race condition by moving the:
win = ipl.getWindow() until AFTER several other interactions take place, all of which cannot proceed until the window is visible. But, this has zero effect on my machine. Another possibility was that the desired window had lost focus - but in that case (i.e., when I do it intentionally) pressing most number keys in 1-6 will invoke some standard ImageJ shortcut, and my "client" reports that "nothing happens" on those keypresses. He has a new version, and if that fails I will go to watch it fail, in person. I still can't reproduce it on my machine. The good news is that I'm cleaning up a lot of cruft by eliminating all the possible problems. None of them have helped, but the code is cleaner... A nagging thought is that the plugin often works 1-4 times in a row on his machine and then fails. Once it fails, it fails forever. Even restarting FIJI seems to have no effect - but re-instaling the plugin does (for at least the first invocation following installation). Very strange! If there are any volunteers, I can put source code on Box and send a link (or just e-mail the source code. It's 1 .java file (467 lines) and (in my opinion) very simple. I'll accept all "pointing and giggling" at my bad coding style. All it does is implement a standard stereology grid, displaying cross-hairs (using overlays) and asking the user to classify each point by typing a number from 1-6. It really shouldn't be this difficult! The hardest problem with intermittent bugs is replicating them! -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Greetings,
The plugin below seems to work for me. Closing the image window restores the key handling back to normal. Note that, in my interpretation of the javadocs for KeyListener, uncommenting the restoration of the ij KeyListener should work the same by including the e.consume() in the callbacks, but alas on the window machine that I am currently on it does not seem to work the same. Does the java virtual machine close down? If it actually has you should not see what you are seeing. FIJI may have closed or only seem to have closed down, but the JVM might be keeping a handle on your objects for some reason. I had the problem ages ago, that a previous version of my plugin was run every time I freshly compiled and ran an updated version of the plugin. Also try and send the JVM a SIGKILL (ctrl-\) and stare at the output... (see previous emails on this subject) Enjoy, Fred import ij.*; import ij.process.*; import ij.gui.*; import java.awt.*; import java.awt.event.*; import ij.plugin.*; import ij.plugin.frame.*; public class My_Keys implements PlugIn, KeyListener, WindowListener { public void run(String arg) { ImagePlus imp = IJ.getImage(); imp.getWindow().getCanvas().removeKeyListener(IJ.getInstance()); imp.getWindow().getCanvas().addKeyListener(this); //imp.getWindow().getCanvas().addKeyListener(IJ.getInstance()); imp.getWindow().getCanvas().requestFocus(); imp.getWindow().addWindowListener(this); IJ.log("stealing keys for '"+imp.getTitle()+"'"); } public synchronized void keyPressed(KeyEvent e) { IJ.log("Pressed: '"+e.getKeyText(e.getKeyCode())); e.consume(); } public void keyTyped(KeyEvent e) { IJ.log("Typed: '"+e.getKeyText(e.getKeyCode())); e.consume(); } public void keyReleased(KeyEvent e) { IJ.log("Releas11red: '"+e.getKeyText(e.getKeyCode())); e.consume(); } public void windowActivated(WindowEvent e) {} public void windowClosed(WindowEvent e) { IJ.log("Bye"); } public void windowClosing(WindowEvent e) { IJ.log("Leaving so soon."); } public void windowDeactivated(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowOpened(WindowEvent e) {} } On Wed, March 18, 2020 1:16 pm, Kenneth Sloan wrote: > I have solved the potential race condition by moving the: > > win = ipl.getWindow() > > until AFTER several other interactions take place, all of which cannot > proceed until the window is visible. But, this has zero effect on my > machine. > > Another possibility was that the desired window had lost focus - but in > that case (i.e., when I do it intentionally) pressing most number keys in > 1-6 will invoke some standard ImageJ shortcut, and my "client" reports > that "nothing happens" on those keypresses. > > He has a new version, and if that fails I will go to watch it fail, in > person. I still can't reproduce it on my machine. > > The good news is that I'm cleaning up a lot of cruft by eliminating all > the possible problems. None of them have helped, but the code is > cleaner... > > A nagging thought is that the plugin often works 1-4 times in a row on his > machine and then fails. Once it fails, it fails forever. Even restarting > FIJI seems to have no effect - but re-instaling the plugin does (for at > least the first invocation following installation). > > Very strange! > > If there are any volunteers, I can put source code on Box and send a link > (or just e-mail the source code. It's 1 .java file (467 lines) and (in my > opinion) very simple. I'll accept all "pointing and giggling" at my bad > coding style. All it does is implement a standard stereology grid, > displaying cross-hairs (using overlays) and asking the user to classify > each point by typing a number from 1-6. It really shouldn't be this > difficult! > > The hardest problem with intermittent bugs is replicating them! > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
yes, well..my code is very similar, and works perfectly on my machine.
the problem is that it does NOT work on at least one other machine. Latest complication: it seems to matter if the image file is read from an external hard drive (on a third machine - not mine). It displays the image and goes through all of the dialog - but fails to register keypresses. That is - the machine handles the external file system fine, but something is going wrong with recognizing keypresses, even when no file access is being requested by the program! I'll get to play with these machines in person...tomorrow. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Greetings,
From what you state below, I suspect that there is something else that is looking at the key strokes on that machine. Is there any other machine(s) that is exhibiting this issue? How do you know that there isn't a sniffer program running on this machine? In regards to my plugin, a) The cause/solution may be in those differences. b) my plugin only does the key handling, the problem may be in the other stuff you are doing. enjoy, Fred On Wed, March 18, 2020 4:59 pm, Kenneth Sloan wrote: > yes, well..my code is very similar, and works perfectly on my machine. > > the problem is that it does NOT work on at least one other machine. > > Latest complication: it seems to matter if the image file is read from an > external hard drive (on a third machine - not mine). It displays the > image and goes through all of the dialog - but fails to register > keypresses. That is - the machine handles the external file system fine, > but something is going wrong with recognizing keypresses, even when no > file access is being requested by the program! > > I'll get to play with these machines in person...tomorrow. > > -- > Kenneth Sloan > [hidden email] > Vision is the art of seeing what is invisible to others. > > -- > ImageJ mailing list: http://imagej.nih.gov/ij/list.html > -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Michael Schmid
Hi Kenneth,
sorry, two corrections to what I had written: (1) ImagePlus.show() waits for the image becoming visible in macros, but not when called from Java. Nevertheless, imp.getWindow() should never return null after imp.show(), except for BatchModeMacros. See https://github.com/imagej/imagej1/blob/master/ij/ImagePlus.java#L490 It will happen, however, that the image does not become the foreground image after imp.show(), so IJ.getImage() or WindowManager.getCurrentImage() may still return a different ImagePlus or null. I do not see why window.setKeyListener(this) (2) If it is possible that your plugin could be called from a macro (e.g. from buttons of the ActionBar plugin) or a macro might be executing while you plugin is used, you should NOT call ImagePlus.show() from the EventQueue (e.g. from a key listener). Also, in the EventQueue, don't wait until the image becomes visible; this won't happen (such a code could cause ImageJ to hang). So the safe strategy is to never call imp.show() in KeyListener callbacks or the like. Rather have a separate thread with imp.show(), retrieving the window and registering as KeyListener. Something like the following: public void keyTyped(KeyEvent e) { if (thisIsTheKeyForOpeningAnImage(e)) { Thread thread = new Thread( new Runnable() { public void run() { ImagePlus imp = .... imp.show(); ImageWIndow win = imp.getWindow(); win.setKeyListener(myPlugin.this); } }, "windowOpenThread"); thread.start(); } } where myPlugin is your main class (implementing KeyListener). What I can also recommend is placing all code in Listeners and new threads in try{ ... } catch(Exception e) {IJ.handleException(e);} blocks. Otherwise you won't notice whether there is an exception in these methods (unless you start ImageJ from the command line with java -jar ij.jar). Michael _______________________________________________ On 18/03/2020 6:07 pm, Michael Schmid wrote: > Hi Kenneth, > > getting KeyListeners: There is method > KeyListener[] Component.getKeyListeners(). > Canvases, Containers (Windows, Panels), and gui elements (checkboxes, > text fields, ...) are java.awt.Components. > > ImagePlus.show() should wait until the window appears, unless you call > it from the EventQueue (e.g. from any Listener). Then you will > experience a 2 sec delay, which is its timeout for waiting (if the image > has not appeared yet in 2 sec). > If you want to create the ImagePlus from the EventQueue, start a new > Thread that creates it. > After spawning the thread, I think you need a loop with maybe 10 msec > delay waiting until the ImagePlus is shown (e.g. check for > imp.getWindow() being non-null and win.isVisible() being true). > If it is possible that your plugin will ever run in a macro, make sure > that it also works in batchmode where no window will be displayed. > > > Michael > _____________________________________________________________ > > > On 18/03/2020 5:52 pm, Kenneth Sloan wrote: >> No joy. The improved(?) version exhibits the same problem. Now on >> two machines (but not yet on mine). The symptoms are that no >> KeyPresses are registered AT ALL. Note that there is a call to IJ.log >> at the start of keyPressed() - so this is not an issue with >> wait/notify. I'm glad I cleaned that up - but it wasn't the problem. >> >> It appears as if the KeyListeners are not being registered. Is there >> a way to double check that a given class has been successfully >> registered as a KeyListener? >> >> It also occurs to me that there might be a race condition here: >> >> ipl.show(); >> win = ipl.getWindow(); >> canvas = win.getCanvas(); >> >> Is it possible that win and canvas may not yet be set, because >> ipl.show() takes some time to complete? Should I add something like >> "wait(1000)" after the ipl.show()"? Is there a direct way to check >> that ipl.show() has finished all of its work before proceeding? >> >> For example...will this help? >> >> ... >> ipl.show(); >> ImageWindow win = null; >> while(null == win) {win = ipl.getWindow();} >> ... >> >> -- >> Kenneth Sloan >> [hidden email] >> Vision is the art of seeing what is invisible to others. >> >> -- >> ImageJ mailing list: http://imagej.nih.gov/ij/list.html >> -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
In reply to this post by Fred Damen
update: The plugin has failed on 2 macs, both in the hands of my client. It works perfectly on my mac, and now we have found that it works perfectly on a WinDoze laptop that I loaned to my client.
Michael Schmid graciously offered to examine the code and test - and could not make it fail. Both failing laptops were originally set up in the Swiss locale, if that matters - and then changed to USA. The plugin senses the Locale and adjusts the format of output files, but otherwise should behave the same way everywhere. I have no idea what other processes may be running on these macs. I'm beginning to suspect there is something about how the plugin is being used by this client - right now I'm focusing on "what happens if you minimize a window currently listening for keypresses, and then run the plugin again?" Or: what happens if there are two independent instantiations of ImageJ running, both trying to listen to the keyboard? I'll be testing that on my mac, today. But...the client is getting his work done, and he is the only one who has ever made it fail, so it's dropping on my priority list. It is *very* strange, though. So...we have a plugin that fails on 2 Swiss Mac laptops in the hands of one user - and nowhere else. And, the user and his wife are in self-quarantine for at least the next week. The good news is that I cleaned up the code considerably while trying to find a bug in the code. I could perhaps do a bit more on that front, but I would rather that my client make actual progress on his work rather than pester him with new versions to test. Finishing the paper takes precedence over solving ImageJ puzzles. Perhaps in a few weeks I will be able to get my hands on one of his laptops, or (perhaps better) be able to watch over his shoulder as he causes it to fail. But, for now, we're done... Thanks to all for your suggestions, and especially to Michael Schmid for testing the plugin in his environment. -- Kenneth Sloan [hidden email] Vision is the art of seeing what is invisible to others. -- ImageJ mailing list: http://imagej.nih.gov/ij/list.html |
Free forum by Nabble | Edit this page |