来自构造函数的repaint()调用

时间:2015-01-21 01:13:07

标签: 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));
    }
}

3 个答案:

答案 0 :(得分:4)

好的,所以很多东西......

首先...

因为屏幕上尚未实现该窗口(附加到本地对等体),所以repaint无需绘制...

其次...

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

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

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

第三...

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

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

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

第四...

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

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

请查看Painting in AWT and SwingPerforming Custom Painting了解详情

第五...

您应确保仅在事件调度线程的上下文中创建和修改UI,有关详细信息,请参阅Initial Threads

答案 1 :(得分:0)

初始化代码时立即调用Paint。要查看此内容,请在构造函数中删除repaint();,然后添加paint方法,g.drawLine(0, 0, 300, 300);

答案 2 :(得分:0)

试试这个,您可能需要添加一些导入:

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");
        setVisible(true);
    }

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

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

资源加载器:

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

public class MyResourceLoader {
    public static Image getImage(String fileName){
        ImageIcon icon = new ImageIcon(getClass().getResource(fileName));
        return icon.getImage();
    }
}