Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 3 of 3

Thread: Getting Image reader to change source

  1. #1
    Junior Member
    Join Date
    Feb 2011
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Getting Image reader to change source

    I'm building an image gallery type program. I want to be able to abort the loading of an image and start loading another. Here's some of the code I've got so far.

    ImageReader reader = null;
    File image1 = "myFile.jpg";
    File image2 = "myFile2.jpg;
    ImagePanel imgPnl = new ImagePanel();
     
    public void loadImage(File f) {
        if(reader != null) reader.abort();
     
        //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());
     
        Thread thread = new Thread(new Runnable() {
            public void run() {
                try {
                    reader.read(0);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
     
        thread.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) {
            imgPnl.setImage(theImage);
        }
        ...
    }

    So, if the image is still loading (from the new thread) I can call loadImage() with a different file and it aborts and then begins to work on the new file. This does work, but pretty quickly I run into errors like this:

    Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to use instance of com.sun.imageio.plugins.jpeg.JPEGImageReader@6c1989b5 locked on thread Thread[Thread-10,6,main] from thread Thread[AWT-EventQueue-0,6,main]

    What's causing this and how do I fix it?


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    Eastern Florida
    Posts
    25,042
    Thanks
    63
    Thanked 2,708 Times in 2,658 Posts

    Default Re: Getting Image reader to change source

    The message says you are trying to use the same instance of a class on two threads.
    Perhaps the class is not thread safe in some way.
    Can you make a new instance for each thread?
    Or synchronize the method that uses it.

  3. #3
    Junior Member
    Join Date
    Feb 2011
    Posts
    13
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Getting Image reader to change source

    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);
     
        }
        ...
    }

Similar Threads

  1. email reader
    By rk.kavuri in forum File I/O & Other I/O Streams
    Replies: 2
    Last Post: March 4th, 2011, 04:59 AM
  2. Buffered Reader to J Option
    By jk_0821 in forum Collections and Generics
    Replies: 13
    Last Post: July 19th, 2010, 03:14 PM
  3. greetings and a file reader problem
    By chileshe in forum File I/O & Other I/O Streams
    Replies: 0
    Last Post: October 6th, 2009, 03:45 AM
  4. [SOLVED] Change the size of an image
    By subhvi in forum Algorithms & Recursion
    Replies: 4
    Last Post: August 23rd, 2009, 11:44 PM
  5. Code to read a character in the file
    By Truffy in forum File I/O & Other I/O Streams
    Replies: 4
    Last Post: May 19th, 2009, 06:11 PM