2

So this is going to sound ridiculous but I am working on a project where I deliberately want to slow down the loading of an image down so that it loads line by line. Is there anyway I can do this? I currently have the image in an ImagePane which is just an extension of a JPanel:

public ImagePane() {
        initComponents();
        image = null;
        //this.setAutoscrolls(true);
    }
    public void setImage(String path) throws IOException {
        image = ImageIO.read(getClass().getResource(path));
    }

    @Override
    public void paintComponent(Graphics g)
    {
        //Graphics2D g2 = (Grahpics2D)g;
        g.drawImage(image, 0,0, this);
    }

And in my window that I'm trying to display this as:

ImagePane image = new ImagePane();
try {
    image.setImage("netscapelogo2.png");
}
catch (IOException e) {
    System.out.print("Failed to Set");
    e.printStackTrace();
}
//jScrollPane1.add(image);
jScrollPane1.setViewportView(image);

I imagine that i need to someone change my paintComponent method to do this but I'm not sure exactly how to do that.

SDSMTKyzer
  • 112
  • 10
  • 3
    If you want the 90's slow loading image experience, you'll have to get the raw pixel data and draw those row by row. See the javadocs for `Image/BufferedImage` (`getRGB()/getRaster()` etc.). – Kayaman Jun 06 '16 at 19:40
  • 1
    I would simulate that the image is loading line by line by uncovering it gradually. – rodrigoap Jun 06 '16 at 19:46

1 Answers1

2

this solution uses the premisse I would simulate that the image is loading line by line by uncovering it gradually. – rodrigoap so the image is loaded at once and only displayed as it would be read line by line!

a solution would be to create a thread and let the thread to the work...

Runnable r = new Runnable(){

    @Override
    run(){
        for(int i = 0; i < image.getHeight(); i++){
            // wait 100ms to 'slow down'
            Thread.sleep(100)// surround with try/catch, it may throw an exception
            line = line + 1; //increase amount of visible lines
            repaint(); //update the panel
        }
    }
}

//i don't know when you want to start the animation
new Thead(r).start(); //so trigger at free will

when you draw the image you just draw a the amount of lines, not the whole image at all...

@Override
public void paintComponent(Graphics g)
{
    super(g);
    int w = image.getWidth();
    int h = image.getHeight();
    g.drawImage(image, 0,0, w, line, 0,0,w,h,this);
}

the drawImage methode is a bit weird, see the docu for further help

of course you need to define the private int line = 0; at some place

Martin Frank
  • 3,445
  • 1
  • 27
  • 47
  • 1
    hmm - i think you can also use a swing timer or something... i forgot about that, but this solution explains, how to solve the problem and can easily be adjustet to other time handler – Martin Frank Jun 07 '16 at 09:37
  • 1
    a timer will be a **much** better solution - dont *ever* simulate your own timing like that -- its unprecise, error-prone and merely a beginners' mistake. Use real timers, `ExecutorServices` and `Lambda` for enhanced readability. Also : use `static final AtomicInteger` instead of `int`, otherwise you **will** run into racing conditions, probably even a solid deadlock – specializt Jun 07 '16 at 09:47
  • 1
    @specializt i know i know - please modify the answer, i'm not very smart on that topic! i know they exists and are the better solution but haven't ever used one! shame on me! – Martin Frank Jun 07 '16 at 09:53
  • Thanks, this helped a lot – SDSMTKyzer Jun 07 '16 at 17:52