Reputation: 50021
I'm loading potentially large images using a javax.imageio.ImageReader for thumbnail generation in a GUI, and when the user navigates to a different folder (on the Swing thread) I'd like to be able to interrupt the thumbnail generator's thread without waiting for the current image to finish loading. So I try calling the ImageReader's abort()
method. But every time, I get this complaint:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to use instance of com.sun.imageio.plugins.jpeg.JPEGImageReader@18e8541 locked on thread Thread[Thumbnail generator,2,main] from thread Thread[AWT-EventQueue-0,6,main]
at com.sun.imageio.plugins.jpeg.JPEGImageReader.setThreadLock(JPEGImageReader.java:1491)
at com.sun.imageio.plugins.jpeg.JPEGImageReader.abort(JPEGImageReader.java:1285)
at ThumbnailGenerator.setDoWork(ThumbnailGenerator.java:81)
at FileList.navigateTo(FileList.java:93)
at App.navigateTo(App.java:199)
at App.navigateUp(App.java:207)
at App$EventListener.keyPressed(App.java:234)
at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:233)
at java.awt.Component.processKeyEvent(Component.java:6246)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2801)
at java.awt.Component.processEvent(Component.java:6065)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1850)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:712)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:990)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:855)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:676)
at java.awt.Component.dispatchEventImpl(Component.java:4523)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
I'm confused. If you can't call abort()
from a different thread, how are you ever supposed to call it at all? (The docs say the abort state is cleared when it starts loading an image.) I've also tried thread.interrupt()
but it has no effect.
Upvotes: 0
Views: 338
Reputation: 109547
Call abort() inside of your own IIOReadProgressListener.
http://docs.oracle.com/javase/1.4.2/docs/guide/imageio/spec/apps.fm7.html
Of course deferring till later might still prove useful, as I suspect the response will not happen immediately:
SwingUtilities.invokeLater(new Runnable() { ... });
Upvotes: 5