java - 从构造函数调用 repaint()

标签 java swing

我正在尝试显示加载的资源图像。 它有效,但只有在用户调整窗口大小时。

import javax.swing.*; import java.awt.*;

class MyMainWindow extends JFrame{
    Image img;

    public MyMainWindow(){
        setSize(300,300);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        img = MyResourceLoader.getImage("res.jpg");
        repaint();

        setVisible(true);
    }
    @Override
    public void paint (Graphics g){
        super.paint(g);
        if (img != null)
            g.drawImage(img, 0,0, null);
    } 
}

public class ResourcesProgram {
    public static void main(String[] args) {
        new MyMainWindow();
    } 
}

为什么构造函数的 repaint() 调用不起作用? 我应该怎么做才能从一开始就显示这张图片?

资源加载器类:

import java.awt.*;

public class MyResourceLoader{
    static MyResourceLoader rl = new MyResourceLoader();
    static public Image getImage(String fileName){
        return Toolkit.getDefaultToolkit().getImage(rl.getClass().getResource("images/" + fileName));
    }
}

最佳答案

好吧,那么一堆东西......

首先...

因为窗口还没有在屏幕上实现(附加到本地对等点),所以repaint没有什么可以绘制的...

第二...

Toolkit.getDefaultToolkit().getImage(rl.getClass().getResource("images/" + fileName));

将图像的实际加载传递给后台线程,这意味着当您返回一个非空值时,实际图像数据可能尚未完全加载。

您应该考虑使用 ImageIO.read,它只会在图像数据完全加载后返回,并且如果出现问题也会抛出异常(不同于 Toolkit.getImage)。参见 Reading/Loading an Image更多详情...

第三...

所有 Swing 组件都实现了 ImageObserver 接口(interface),这意味着当您调用 Graphics#drawImage 时,您应该将对象作为 ImageObserver 参数传递

g.drawImage(img, 0,0, this);

这允许组件监 View 像加载的更新并根据需要重新安排重绘。

第四...

你应该避免重写顶级容器的paint,除了没有双缓冲,框架和用户之间有一堆组件,这会干扰绘画过程。

相反,您应该从类似JPanel 的东西扩展并覆盖它的paintComponent 方法,在那里执行您的自定义绘画。然后,您应该将此面板添加到 JFrame 的实例(或根据需要添加到其他组件)

看看Painting in AWT and SwingPerforming Custom Painting了解更多详情

第五...

您应该确保仅在事件调度线程的上下文中创建和修改您的 UI,请参阅 Initial Threads了解更多详情

关于java - 从构造函数调用 repaint(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28058006/

相关文章:

java - 从 Apache Ant 运行 JUnit 并包含 jar 文件会导致 "JUnitTask was not found"

java - 客户端/服务器套接字 Java(模式 MVC)未向客户端发送正确的信息

java - 为什么没有选项可以使用自定义消息重新抛出异常?

java - 将 XML 解析值添加到 JList 中不起作用

Java Gui 线程编码?

java - 如何防止我的 JPanel 重新调整

java - 如何根据 2 个参数查询 SQLite 表?

java - 在基于 Spring MVC 的 Web 应用程序中,如何判断用户是否提交了具有更改值的表单?

java - 使用 Spring 进行 Swing GUI 开发

java - JOptionPane 对话框 - 存在额外行的问题