Java Swing:为啥我不能在 JFrame 实例上绘制图像()?

Posted

技术标签:

【中文标题】Java Swing:为啥我不能在 JFrame 实例上绘制图像()?【英文标题】:Java Swing: Why can't I drawImage() on an instance of JFrame?Java Swing:为什么我不能在 JFrame 实例上绘制图像()? 【发布时间】:2015-10-07 19:36:08 【问题描述】:

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

我知道这不是公认的执行此操作的方式,但是在我对 Swing 以及它如何绘制组件的理解中,发现未绘制图像暴露了一个缺失的链接(我想是其中之一)。

让我感到困惑的是,如果我的程序子类化了 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?

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

try

    Thread.sleep(1000);
    Graphics g = window.getGraphics();
    paint(g);

catch(Exception e)  e.printStackTrace(); 

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

如果我的程序子类化了 JFrame 并且我重写了 paint() 方法

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

如果问题主要是由于我对 Swing 工作原理的严重误解

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

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

【讨论】:

感谢 camickr。我认为这有帮助。延迟线程的技巧实际上非常揭示幕后似乎发生的事情。无论如何,我已经检查了你过去提到的所有资源,但我会再次浏览它们,看看我可能错过了什么。

以上是关于Java Swing:为啥我不能在 JFrame 实例上绘制图像()?的主要内容,如果未能解决你的问题,请参考以下文章

JAVA SWING 用了JDialog的模态窗口后,为啥监听器没反应了?

无法导入 javax.swing.JFrame

java形式的未修饰jframe中的Java相对定位swing组件

java swing问题:JFrame根面板不透明且可见,内容面板不透明且可见,层面板透明且可见,

frame和jframe的区别

javax.swing.jFrame