Java 等待组件被绘制

标签 java swing jpanel jcomponent

我正在尝试用 Java 创建一个程序,它可以一个接一个地显示一组图像,并调整每个图像的框架大小。 我正在扩展 JPanel 以显示这样的图像:

public class ImagePanel extends JPanel{

String filename;
Image image;
boolean loaded = false;

ImagePanel(){}

ImagePanel(String filename){
    loadImage(filename);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    if(image != null && loaded){
        g.drawImage(image, 0, 0, this);
    }else{
        g.drawString("Image read error", 10, getHeight() - 10);
    }
}

public void loadImage(String filename){
    loaded = false;         
    ImageIcon icon = new ImageIcon(filename);
    image = icon.getImage();
    int w = image.getWidth(this);
    int h = image.getHeight(this);
    if(w != -1 && w != 0 && h != -1 && h != 0){
        setPreferredSize(new Dimension(w, h));
        loaded = true;
    }else{
        setPreferredSize(new Dimension(300, 300));
    }
}

然后在事件线程中我正在做主要工作:

        SwingUtilities.invokeLater(new Runnable(){

        @Override
        public void run(){
            createGUI();
        }
    });

在 createGUI() 中,我将浏览图像集:

        ImagePanel imgPan = new ImagePanel();
    add(imgPan);

    for(File file : files){
        if(file.isFile()){
            System.out.println(file.getAbsolutePath());

            imgPan.loadImage(file.getAbsolutePath());
            pack();

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } 
        }
    }

问题是我的程序正确地调整了大小,所以图像被正确加载但它不显示任何东西。 如果我只显示一张图片,它也适用于最后一张图片。我认为问题在于 Thread.sleep() 在图像绘制完成之前被调用。

我如何才能等待我的 ImagePanel 完成绘制并在之后开始等待? 或者有其他方法可以解决这个问题吗?

谢谢! 莱昂蒂

最佳答案

您的所有代码都在事件调度线程上执行。这有效地导致所有用户交互进入 hibernate 状态,因为事件调度线程负责所有用户交互 - 输入(事件)和输出(绘画)。

您需要在 EDT 之外等待。您需要知道如何在 EDT 内外执行事件。为此,您可以创建一个新的 Runnable,然后调用 new Thread(runnable) 从 EDT 或 SwingUtilities.invokeLater(runnable) 执行它> 使其在 EDT 上执行。与 Swing 组件的所有交互都需要在 EDT 上进行,因为 Swing 对象不是线程安全的。所有 hibernate 、等待、文件访问、网络访问、数据库访问或任何其他可能会在不确定的时间段内阻塞的事情都必须在 EDT 之外进行。

Stack Overflow 上有很多与事件调度线程有关的问题。我建议您查看这些内容以找到更多信息和代码示例,以不同的方式完成您想做的事情。

关于Java 等待组件被绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4402179/

相关文章:

java - 如何调整GridBagLayout中JPanel的大小?

java - 按钮、jFrame、jPanel,我无权访问方法

java - 2 个 JButtons 2 GUI

java - 使用 AssetsManager 在 Java libgdx 上出错

java - 如何检查java中字符串中存在的错误字符

java - instanceof 被认为是不好的做法吗?如果是这样,在什么情况下instanceof仍然更可取?

java - JDatePicker jar 找不到本地 en_GB?

java - 从 JApplet 更改为 JFrame

java - 向 JPanel 添加其他 JPanel

java - 检查Java中持有对象的引用的类名