为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕尼黑5688855 2019-10-22 22:19:54
原始问题:应该使用此方法将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);}
查看完整描述

3 回答

?
呼如林

TA贡献1798条经验 获得超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

{

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

    }

}


查看完整回答
反对 回复 2019-10-22
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

k上的循环应该是最外面的循环。现在,您正在调用Thread.sleep k * width * height次。


查看完整回答
反对 回复 2019-10-22
  • 3 回答
  • 0 关注
  • 475 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信