Java Swing:为什么我不能在 JFrame 实例上使用 drawImage()?

Java Swing: Why can't I drawImage() on an instance of JFrame?

在不深入细节的情况下,我正致力于在 Swing 中创建类似桌面的程序,在背景图像上绘制图标。通常我子类化 JPanel 或另一个 JComponent 并在其上进行绘制,但想尝试一些新的东西只是为了好玩,并尝试在 JFrame 的 instance 上进行绘制,而不是让我的程序成为它的子类。

我知道这不是公认的做法,但发现图像不是绘制的,这暴露了我对 Swing 的理解中缺失的 link(我想是众多缺失之一)以及它如何绘制组件。

让我感到困惑的是,如果我的程序子类化 JFrame 并且我重写了 paint() 方法(换句话说,可接受的方式),它会将图像绘制到 JFrame 中,但它不会这样做我的非子类程序中的 JFrame 实例。

希望基本上显示我想做的事情的代码能有所帮助:

public class ImageLoader
{
    BufferedImage img = null;
    JFrame window = null;

public ImageLoader()
{
    try
    {
        img = ImageIO.read(new File("src/strawberry.jpg"));
    }catch(IOException e)
    {
        e.printStackTrace();
    }

    window = new JFrame("Strawberry Viewer");

    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    window.pack();
    window.setVisible(true);

    //Why can't I do something akin to the following to draw on an instance of JFrame?
    Graphics g = window.getGraphics();
    paint(g);
}

public void paint(Graphics g)
{
    g.drawImage(img, 0, 0, null);
}

public static void main(String[] args)
{
    new ImageLoader();
}

}

我已经阅读了 Oracle 的页面 "Painting in AWT and Swing",但我仍然不明白为什么我不能在 JFrame 的实例上绘图。在任何情况下我都可以在一个组件的实例上绘制,或者如果我想在它们上绘制它们是否都必须被子类化?

最后,如果问题主要是由于我对 Swing 工作原理的严重误解,有哪些推荐的书籍或其他资源可以帮助您理解 Swing?

提前感谢您的帮助。我很感激。

不要使用 getGraphics() 进行绘画。

您对该 Graphics 对象所做的任何操作都只是暂时的。然后下次 Swing 确定框架需要重新绘制时,您将失去绘画。

在您的情况下,您使用 pack() 以便将框架最小化。当您调整框架大小时,正常的框架绘画将覆盖您的图像。所以尝试使用 setSize(500, 500);.

然而,即使这样也行不通,因为您的图像将在正常绘制完成之前进行绘制。并非所有代码都按顺序执行。

尝试以下方法来延迟图像的绘制:

try
{
    Thread.sleep(1000);
    Graphics g = window.getGraphics();
    paint(g);
}
catch(Exception e) { e.printStackTrace(); }

当图像显示时,然后尝试调整框架大小,您将丢失图像。

if my program subclasses JFrame and I override the paint() method

不要重写 JFrame 的 paint()(是的,它会起作用,但它不是设计用于在 Swing 中完成绘画的方式)。自定义绘画是通过覆盖 JPanel 的 paintComponent() 然后将面板添加到框架来完成的。

if the problem is based largely on my gross misunderstanding of how Swing works

Swing 教程是学习 Swing 基础知识的最佳起点。请参阅 Custom Painting 部分以开始使用。

有关更多技术文章,请参阅 Painting in AWT and Swing