【问题标题】:JFrame image display at frame resize调整帧大小时的 JFrame 图像显示
【发布时间】:2011-09-29 14:47:55
【问题描述】:

我有一个包含 JPanel 子级的 JFrame,其中显示了以这种方式声明的图像。

BufferedImage image = ImageIO.read(filename);

程序正确显示图像。但唯一的问题是,它需要调整框架的大小才能显示图像。

有没有一种方法可以在框架出现后显示图像?

【问题讨论】:

  • 可能是因为您在显示框架后添加图像。作为解决方案,您应该首先添加图像然后使框架可见,或者您也可以在添加图像后调用 repaint()。
  • @Cyril Horad,如果您提供更多示例代码会有所帮助。
  • 您能否将评论作为清除线程的答案。谢谢。我会接受答案。
  • 也许,您可以尝试在您自己的扩展 JPanel 的类中再次实现 paint 方法,如下所示:pastebin.com/3ZwVvr2v 并确保在创建 JPanel 时调用 super.paintComponent(g) 以便JFrame 是用图像绘制的。
  • @Cyril Horad,你永远不应该显式调用 paint(...) 或覆盖它。

标签: java swing jframe bufferedimage javax.imageio


【解决方案1】:

您应该覆盖paintComponent(Graphics g) 并在其中绘制图像。在这种情况下,您应该为 JPanel 组件执行此操作(我认为?如果不是,请为您所指的 JComponent(s) 执行此操作)。此外,由于 Swing 不是线程安全的,请确保在 EDT 中执行这些修改。

示例

public class Demo{
    private static BufferedImage bi;
    
    public static void main(String[] args){
        try{
            loadImage();
            
            SwingUtilities.invokeLater(new Runnable(){
                @Override
                public void run(){
                    createAndShowGUI();
                }
            });
        }
        catch (IOException e){
            // handle exception
        }
    }
    
    private static void loadImage() throws IOException{
        bi = ImageIO.read(new File("src/resource/braveheart.PNG"));
    }
    
    private static void createAndShowGUI(){
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final JPanel panel = new JPanel(){
            @Override
            protected void paintComponent(Graphics g){
                Graphics g2 = g.create();
                g2.drawImage(bi, 0, 0, getWidth(), getHeight(), null);
                g2.dispose();
            }
            
            @Override
            public Dimension getPreferredSize(){
                return new Dimension(bi.getWidth(), bi.getHeight());
            }
        };
        
        frame.add(panel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

输出

请务必记住,此示例忽略了渲染提示,因此当您最大化 JFrame 时,图像质量会很差。 :)

编辑

在回答这个问题时,我假设您对 Swing 有基本的了解。我想我假设太多了。值得一提的是,所有组件都应该在顶级容器被实现(即可见)之前添加到它。这将确保在无需调整框架大小的情况下渲染所有内容。正如其他人所建议的那样,您可以简单地使用JLabel 来渲染图像,然后将其添加到您的JPanel。相反,我提倡定制绘画,这是完全可以接受的,而且对我来说更干净。

【讨论】:

  • paint(Graphics g) 和paintComponent(Graphics g) 有什么区别?
  • @Cyril Horad,paint(...) 处理任何 Swing 组件的内容、边框和子项的绘制,而 paintComponent(...) 用于渲染 Swing 组件,并在需要自定义渲染时被覆盖。
  • 为什么要推广自定义绘画而不是使用 JLabel?我一直认为编程的目标之一是不要重新发明轮子。
  • 任何时候你扩展一个类都是自定义代码。在直接支持功能时添加自定义代码对我来说是“重新发明轮子”。此外,这个问题不是关于如何绘画,而是关于如何在显示框架时显示图像。您在回答中没有提到真正的问题是 setVisible() 的使用。现在发帖者认为解决方案是 paintComponent() 方法,而不是在将组件添加到框架后调用 setVisible
  • 显示文本时是使用 JLabel,还是创建自定义组件并使用 Graphics.drawString() 方法?我猜您使用的是 JLabel,那么为什么您更喜欢自定义绘制图像而不是让 JLabel 为您完成所有工作呢?我不想在这里成为一个痛苦的人。老实说,我不明白其中的区别。
【解决方案2】:

对于显示ImageImageIcon 更好地寻找JLabel(基本的东西)

【讨论】:

  • +1,我同意,使用现有组件而不是重新发明轮子。
  • @camickr,有趣的是你如何投票(因为这个答案与你的意见一致),尽管@mKorbel 忽略了解决最初的问题。这就是为什么我对你的批评持保留态度。 :)
  • @little bunny foo foo,一点都不好笑。这就是支持答案的重点。你投票选出你认为最好的方法。我相信使用 JLabel 显示图像比使用自定义代码更好。不管这是否解决了问题,它仍然是一个真实的陈述。每当我发表评论时,我都会给出评论的理由,以便人们可以做出明智的决定。在不给出任何理由的情况下陈述某事“更可取”毫无意义:)
  • @camickr,哈哈哈我觉得很好笑。
  • @camickr @little bunny foo foo,请最后关灯,Rob ++
猜你喜欢
  • 2012-05-16
  • 2012-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-29
  • 2015-04-16
  • 1970-01-01
相关资源
最近更新 更多