Java对revalidate()和repaint()的使用不正常

Java对revalidate()和repaint()的使用不正常,java,swing,Java,Swing,所以我试着创建一个框架来进行演示,但由于某种原因,我只能看到一个空的框架,在一切完成后,我看到最后一张图片。我想看到的是每张照片中间都有~1秒的停顿。我使用了revalidate()/repaint(),我认为它的工作方式是这样的,但我相当肯定问题就在那里,因为我想不出其他原因 我才刚刚开始学习Java.Swing,所以非常欢迎任何输入来提高我的技能。正如我已经说过的,我认为问题在于我对revalidate()的使用,但我不能单独用谷歌来解决它 作为类的输入,我使用了一个buffereImage

所以我试着创建一个框架来进行演示,但由于某种原因,我只能看到一个空的框架,在一切完成后,我看到最后一张图片。我想看到的是每张照片中间都有~1秒的停顿。我使用了revalidate()/repaint(),我认为它的工作方式是这样的,但我相当肯定问题就在那里,因为我想不出其他原因

我才刚刚开始学习Java.Swing,所以非常欢迎任何输入来提高我的技能。正如我已经说过的,我认为问题在于我对revalidate()的使用,但我不能单独用谷歌来解决它

作为类的输入,我使用了一个buffereImage数组,我想为其创建diashow

我还尝试将图像直接放在我的容器c上,而不是放在JPanel p上,但这两种方式都不起作用

public class DiashowFrame extends JFrame {

Container c;
JPanel p;

public DiashowFrame(JFrame father,BufferedImage [] image) {
    c= getContentPane();
    c.setLayout(new FlowLayout());
    p = new JPanel();
    p.setLayout(new FlowLayout());
    p.setSize(500,500);
    c.add(p);

    setSize(500,500);
    setLocation(father.getX(),father.getY());
    setVisible(true);
    dia(p,image);

}

public static void dia(JPanel p,BufferedImage[] image) {

    JLabel def= new JLabel(new ImageIcon(image[0]));
    p.add(def);
    //c.repaint();
    p.revalidate();
    for(int x=1;x<image.length;x++) {

    try {

        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //p.removeAll();
    //p.revalidate();
    Image imager = image[x].getScaledInstance(500, 500, 100);
    def = new JLabel(new ImageIcon(imager));
    p.add(def);
    p.revalidate();
    //p.repaint();

    }

}
public类DiashowFrame扩展了JFrame{
容器c;
JPanel p;
公共显示帧(JFrame父帧,BuffereImage[]图像){
c=getContentPane();
c、 setLayout(新的FlowLayout());
p=新的JPanel();
p、 setLayout(新的FlowLayout());
p、 设置大小(500500);
c、 加(p);
设置大小(500500);
setLocation(父.getX(),父.getY());
setVisible(真);
直径(p,图像);
}
公共静态无效直径(JPanel p,BuffereImage[]图像){
JLabel def=新JLabel(新图像图标(图像[0]);
p、 添加(def);
//c、 重新油漆();
p、 重新验证();
对于(intx=1;x来说,首先看一看

和大多数GUI框架一样,Swing是单线程的,并且不是线程安全的

这意味着在事件调度线程中执行的任何长时间运行或阻塞操作都将阻止EDT处理事件队列,并无论如何更新UI

虽然您可以使用
线程
将等待时间转移到第二个线程,但Swing不是线程安全的,这意味着您永远不应该直接或间接地从EDT上下文之外更新/修改UI

在您的情况下,最简单的解决方案是简单地使用Swing
计时器。这允许您指定更新之间的延迟(以及是否重复),该延迟在EDT之外执行,但在触发时,会在EDT的上下文中得到通知,从而使Swing的使用更加方便和安全

计时器
充当伪循环,计时器的每个触发器
表示下一次迭代


有关更多详细信息,请参阅不要在事件调度线程中休眠,您将阻止EDT处理新的更新请求并绘制屏幕。相反,请使用Swing
计时器