I thought about using only one instance, but if my next file is in a different format, I need a new ImageReader.
I was just looking into Thread.join() and I thought the problem could be that I'm not waiting for the thread using the ImageReader to terminate properly. I now store a reference to the reader thread and interrupt() + join() on it when trying to load a different image. I also put an interrupted check in one of the frequently called methods in the IIORead listeners.
So far so good, no errors yet. Hope this is a decent way of handling this situation; I'm new to thread programming.
ImageReader reader = null;
File image1 = "myFile.jpg";
File image2 = "myFile2.jpg;
ImagePanel imgPnl = new ImagePanel();
Thread activeThread = null;
public void loadImage(File f) {
if(activeThread != null) {
if(activeThread.getState() != Thread.State.TERMINATED) {
try {
activeThread.interrupt();
activeThread.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
//get file extention
String filename = f.getName();
int pos = filename.lastIndexOf('.');
String ext = filename.substring(pos+1);
Iterator readers = ImageIO.getImageReadersByFormatName(ext);
ImageInputStream iis = null;
try {
iis = ImageIO.createImageInputStream(f);
} catch (IOException ex) {
ex.printStackTrace();
}
reader = (ImageReader) readers.next();
reader.setInput(iis);
reader.addIIOReadProgressListener(new MyProgressListener());
reader.addIIOReadUpdateListener(new MyUpdateListener());
activeThread = new Thread(new Runnable() {
public void run() {
try {
reader.read(0);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
activeThread.start();
}
// Component that draw a BufferedImage
class ImagePanel extends JPanel {
private BufferedImage img;
public void setImage(BufferedImage img) {
this.img = img;
this.repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(img != null)
g.drawImage(img, 0, 0, null);
}
}
class MyProgressListener implements IIOReadProgressListener {
...
}
class MyUpdateListener implements IIOReadUpdateListener {
...
public void imageUpdate(ImageReader source, BufferedImage theImage, int minX, int minY, int width, int height, int periodX, int periodY, int[] bands) {
if(Thread.interrupted()) {
source.abort();
return;
}
imgPnl.setImage(theImage);
}
...
}