程序冻结...使用Timer设置循环延迟

时间:2011-10-19 06:09:07

标签: java image image-processing timer freeze

此方法应该将正在JFrame上显示的图像逐渐更改为另一个图像。但是,如果没有某种方法可以减慢速度,它似乎只会从一个图像变为新图像。为了减慢速度,我输入了一个Thread.sleep(1000),这样就不会立即发生变化。但是,有了这一行,我的程序完全冻结了。然后我尝试放入一个计时器,如下所示,但程序在运行时没有显示任何变化。它仍然在完全相同的点冻结。有人可以帮帮我吗?建议一种更好的方法来减慢速度,或者如何解决这个问题。

澄清:int k是变化中渐进步骤的数量。 k = 1将是瞬间变化。任何更大的东西都是渐进的变化。 int l同时控制每个图像显示的比例。

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

注意:问题是此处发布的问题的更新Program freezes during Thread.sleep() and with Timer

1 个答案:

答案 0 :(得分:0)

您当前正在循环的每次迭代中创建一个计时器,但仍然一次性执行 all 迭代。相反,你应该:

  • 为侦听器编写一个类以附加到计时器
  • 将状态放在侦听器类中,用于当前作为局部变量获取的所有变量,并使actionPerformed方法执行循环的单次迭代,实现
  • 创建该侦听器类的实例
  • 使用侦听器作为唯一的初始侦听器
  • 创建单个计时器
  • 在每个计时器“tick”上,将调用actionPerformed(在UI线程上),您将运行循环的单次迭代,并且UI将更新

代码看起来有些难看,因为你基本上必须手工编写for循环的代码 - 增加j,如果现在等于height那么将其设置为0并增加i;如果 现在等于width,则将其设置为0并增加l;如果 现在大于k,则停止计时器。

Read the tutorial on Swing timers了解更多信息。