0

This method is supposed to change the image being displayed on a JFrame gradually into another image. However, without some way to slow it down, it just seems to change from one image to the new image. In order to slow it down, I put in a Thread.sleep(1000) so the changes wouldn't happen instantly. However, with this line in there, my program freezes completely. I then tried putting in a timer, as shown below, but the program showed no change when running. It still froze at the exact same point. Can anyone please help me out? Suggest a better method to slow it down, or how this can be fixed.

For clarification: int k is the number of gradual steps in the change. k = 1 would be an instant change. Anything greater would be gradual changes. int l meanwhile controls the ratio of how much of each image is displayed.

public void morphImg(int width, int height, BufferedImage morphImage, int k) {
    //creates new image from two images of same size
    final BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    for (int l = 1; l <= k; l++) {
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                //get color from original image
                Color c = new Color(image.getRGB(i, j));

                //get colors from morph image
                Color c2 = new Color(morphImage.getRGB(i, j));

                //gets colors at different stages
                int r = ((k-l)*c.getRed()/k) + (l*c2.getRed()/k);
                int g = ((k-l)*c.getGreen()/k) + (l*c2.getGreen()/k);
                int b = ((k-l)*c.getBlue()/k) + (l*c2.getBlue()/k);   
                Color newColor = new Color(r, g, b);

                //set colors of new image to average of the two images
                image2.setRGB(i, j, newColor.getRGB());
                //display new image

                imageLabel.setIcon(new ImageIcon(image2));
                final Timer t = new Timer(500,null);
                t.setInitialDelay(500);
                t.start();
            }
        }
    }

    //sets modified image as "original" for further manipulation
    setImage(image2);
}

Note: Question is an update to question posted here Program freezes during Thread.sleep() and with Timer

Community
  • 1
  • 1
Ruben Martinez Jr.
  • 3,199
  • 5
  • 42
  • 76
  • You've created a timer, but not told it to *do* anything. What did you imagine that timer would really do? You also say "to no avail" but you don't specify what you've observed since putting that code in place. – Jon Skeet Oct 19 '11 at 06:13
  • @JonSkeet By "to no avail", I mean to say nothing at all has changed. Program is still freezing in much the same way as it was when the Thread.sleep() line was there. As for the timer, I'm very hazy on how to implement it properly...I was hoping for help :/ – Ruben Martinez Jr. Oct 19 '11 at 06:17
  • 1
    Ah, that's better. You weren't indicating *from which position* nothing had changed. I suspect it's freezing because you're creating a *huge* number of timers in a very short space of time. – Jon Skeet Oct 19 '11 at 06:20

1 Answers1

0

You're currently creating one timer on each iteration of the loop, but still performing all the iterations in one go. Instead, you should:

  • Write a class for the listener to attach to the timer
  • Put state in the listener class for all the variables which you've currently got as local variables, and make the actionPerformed method perform a single iteration of your loop, effectively
  • Create an instance of that listener class
  • Create a single timer with the listener as the sole initial listener
  • On each timer "tick", actionPerformed will be called (on the UI thread), you'll run a single iteration of your loop, and the UI will update

The code's going to look somewhat ugly, because you've basically got to write the code for your for loop by hand - increment j, and if that now equals height then set it to 0 and increment i; if that now equals width then set it to 0 and increment l; if that is now greater than k then stop the timer.

Read the tutorial on Swing timers for more information.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194