java – 程序在Thread.sleep()和Timer期间冻结

原始问题:

该方法应该将在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
    BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    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));

            for (int l = 1; l <= k; l++) {
                //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
                try {
                    imageLabel.setIcon(new ImageIcon(image2));
                    Thread.sleep(1000);
                }
                catch (InterruptedException e){
                    System.out.println("Exception caught.");
                }
            }
        }
    }

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

更新的代码:使用计时器也会导致程序冻结…我没有使用它吗?

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

解决方法:

在Event Dispatch Thread上执行代码时,切勿使用Thread.sleep().

相反,您应该使用Swing Timer来安排动画.

请参阅Swing tutorial上的部分:

> Swing中的并发性
>如何使用计时器

或者,如果您不想使用Timer,那么您可以使用SwingWorker(如并发教程中所述),然后在更改后再发布()图像.然后你可以使用Thread.sleep(),因为SwingWorker不在EDT上执行.

简单定时器示例:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class TimerTime extends JFrame implements ActionListener
{
    JLabel timeLabel;

    public TimerTime()
    {
        timeLabel = new JLabel( new Date().toString() );
        getContentPane().add(timeLabel, BorderLayout.NORTH);
    }

    public void actionPerformed(ActionEvent e)
    {
        timeLabel.setText( new Date().toString() );
    }

    public static void main(String[] args)
    {
        TimerTime frame = new TimerTime();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.pack();
        frame.setVisible(true);

        int time = 1000;
        javax.swing.Timer timer = new javax.swing.Timer(time, frame);
        timer.setInitialDelay(1);
        timer.start();
    }
}
上一篇:java-从JPanel(不带JFrame)创建BufferedImage时,是否还可以使用布局管理器?


下一篇:后台管理系统