猿问

程序在Thread.sleep()期间并与Timer冻结

原始问题:


应该使用此方法将JFrame上显示的图像逐渐更改为另一图像。但是,如果没有某种方法可以减慢它的运行速度,它似乎只能从一个图像更改为新图像。为了减慢速度,我放入Thread.sleep(1000),这样更改不会立即发生。但是,有了这一行,我的程序完全死机了。没有错误信息,什么都没有。有人可以帮我吗?建议一种更好的方法来降低它的速度,或解决该问题的方法。


为了澄清起见:int k是更改中的渐进步骤数。k = 1将是即时变化。更大的事情将是逐渐的变化。同时,int控制每个图像显示多少的比例。


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

}


慕尼黑5688855
浏览 507回答 3
3回答

呼如林

在事件调度线程上执行代码时,切勿使用Thread.sleep()。相反,您应该使用Swing计时器来安排动画。请参阅Swing教程中有关以下内容的部分:Swing中的并发如何使用计时器或者,如果您不想使用Timer,则可以使用SwingWorker(如并发教程中所述),然后在更改图像后只发布()图像。然后,由于SwingWorker不在EDT上执行,因此可以使用Thread.sleep()。简单的计时器示例:import java.awt.*;import java.awt.event.*;import java.util.*;import javax.swing.*;public class TimerTime extends JFrame implements ActionListener{&nbsp; &nbsp; JLabel timeLabel;&nbsp; &nbsp; public TimerTime()&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; timeLabel = new JLabel( new Date().toString() );&nbsp; &nbsp; &nbsp; &nbsp; getContentPane().add(timeLabel, BorderLayout.NORTH);&nbsp; &nbsp; }&nbsp; &nbsp; public void actionPerformed(ActionEvent e)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; timeLabel.setText( new Date().toString() );&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; TimerTime frame = new TimerTime();&nbsp; &nbsp; &nbsp; &nbsp; frame.setDefaultCloseOperation( EXIT_ON_CLOSE );&nbsp; &nbsp; &nbsp; &nbsp; frame.pack();&nbsp; &nbsp; &nbsp; &nbsp; frame.setVisible(true);&nbsp; &nbsp; &nbsp; &nbsp; int time = 1000;&nbsp; &nbsp; &nbsp; &nbsp; javax.swing.Timer timer = new javax.swing.Timer(time, frame);&nbsp; &nbsp; &nbsp; &nbsp; timer.setInitialDelay(1);&nbsp; &nbsp; &nbsp; &nbsp; timer.start();&nbsp; &nbsp; }}

慕虎7371278

k上的循环应该是最外面的循环。现在,您正在调用Thread.sleep k * width * height次。
随时随地看视频慕课网APP

相关分类

Java
我要回答