Boann
Boann

Reputation: 50021

How do I use ImageReader.abort()?

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

Answers (1)

Joop Eggen
Joop Eggen

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

Related Questions