简体   繁体   English

Java对revalidate()和repaint()的用法无法正常工作

[英]Java usage of revalidate() and repaint() not properly working

So I tried creating a frame to perform a Diashow, but for some reason, I can see the only an empty frame and after everything is done, I see the last picture. 因此,我尝试创建一个框架来执行Diashow,但是由于某种原因,我只能看到一个空框架,完成所有操作后,我可以看到最后一张图片。 What I wanted to see was each picture with a ~1 second pause in between. 我想看的是每张照片之间有〜1秒的暂停时间。 I used revalidate() / repaint() the way I suppose it is working, but Im fairly certain that the problem is there, since I cant think of another reason. 我以我认为它起作用的方式使用了revalidate()/ repaint(),但是我很确定问题出在这里,因为我想不出另一个原因。

I am only starting to learn Java.Swing, so any input is really welcome to improve my skills. 我只是开始学习Java.Swing,因此,欢迎您输入任何信息来提高自己的技能。 As I already said, I assume that the problem lies with my usage of revalidate(), but I cant fix it alone with google.. 正如我已经说过的那样,我认为问题出在我对revalidate()的使用上,但是我无法单独使用Google来解决它。

As input to the class I use an array of BufferedImage ,for which I want to create the diashow. 作为类的输入,我使用BufferedImage数组,我想为其创建diashow。

I also tried putting the images directly on my Container c instead of on the JPanel p , but it doenst work either way I intend it to work. 我还尝试将图像直接放在我的Container 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();

    }

}

} }

Start by taking a look at Concurrency in Swing . 首先看一下Swing中的并发

Swing, like most GUI frameworks, is single threaded AND not thread safe. 与大多数GUI框架一样,Swing是单线程的,并且不是线程安全的。

This means that any long running or blocking operation executed from within the Event Dispatching Thread will prevent the EDT from processing the Event Queue and update the UI in anyway. 这意味着从事件调度线程中执行的任何长时间运行或阻止的操作都将阻止EDT处理事件队列并以任何方式更新UI。

While you could use a Thread to offload the wait time to a second thread, Swing is NOT thread safe, meaning you should never update/modify the UI directly or indirectly from outside the context of the EDT. 尽管您可以使用Thread将等待时间转移到第二个线程,但Swing并不是线程安全的,这意味着您切勿直接或间接在EDT上下文之外更新/修改UI。

The simplest solution in your case is to simply use a Swing Timer . 在这种情况下,最简单的解决方案是仅使用Swing Timer This allows you to specify a delay between updates (and if it's repeating or not), which is executed off the EDT, but when triggered, is notified within the context of the EDT, making easy and safe to use with Swing. 这使您可以指定两次更新之间的延迟(以及是否重复),该延迟是在EDT上执行的,但是在触发时会在EDT的上下文中得到通知,从而使Swing易于安全使用。

The Timer acts as a pseudo loop, each trigger of the Timer representing the next iteration Timer充当伪循环, Timer每个触发器代表下一次迭代

See How to use Swing Timers for more details 有关更多详细信息,请参见如何使用Swing计时器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM