【问题标题】:JLabel is painted twiceJLabel 涂了两次
【发布时间】:2015-07-09 06:18:16
【问题描述】:

在我开始之前,让我说我对 Java 很陌生。我提前为我的无知道歉。

因此,我创建了一个 JFrame,将图像加载为 ImageIcon,并将其转换为 JLabel,然后将其添加到 Frame 中。问题是,控制标签的大小和位置很痛苦。

我找到了这个解决方案:

        final ImageIcon image = new ImageIcon(loadFrames.class.getResource("/images/testimage.png"));


    JLabel imageLabel = new JLabel(image){

        @Override
        public void paintComponent (Graphics g) {
            super.paintComponent (g);
                if (image != null) {
                    g.drawImage (image.getImage(), 300, 0, image.getIconWidth(), image.getIconHeight(), null);
                }
            }
        };

        gameFrame.add(imageLabel);  

        imageLabel.setVisible(true);
        gameFrame.setVisible(true);

如您所见,我在网上找到了一个响应,其中显示了 Graphics 对象的用法。我不知道它是如何工作的或为什么会工作,但确实如此。问题是,图像被绘制了两次。一次在原点(中心)和一次在 (300,0)。

感谢您提供有关如何阻止它在原始位置绘制的任何反馈。如果您知道一种更简单的方法来调整标签的大小和位置,也请说出来。我没有使用 LayoutManager。

【问题讨论】:

  • 避免使用null 布局,像素完美的布局是现代用户界面设计中的一种错觉。影响组件单个尺寸的因素太多,您无法控制。 Swing 旨在与核心布局管理器一起工作,丢弃这些将导致无穷无尽的问题和问题,您将花费越来越多的时间来尝试纠正

标签: java swing


【解决方案1】:

您为JLabel 提供了ImageIcon...

JLabel imageLabel = new JLabel(image)

然后覆盖它的paintComponent 方法并手动绘制它...

JLabel imageLabel = new JLabel(image){
    @Override
    public void paintComponent (Graphics g) {
        super.paintComponent (g);
            if (image != null) {
                g.drawImage (image.getImage(), 300, 0, image.getIconWidth(), image.getIconHeight(), null);
            }
        }
    };

...不太确定您预期会发生什么...

JLabel 是显示图像的默认方式。

调用drawImage时,你应该将this作为ImageObserver传递,这是所有Swing组件都实现的,尤其是在使用ImageIcon加载图像时,因为到组件时图像可能还没有完成加载是第一次画。使用this 作为ImageObserver 允许组件在图像加载状态发生变化时自动安排重绘

也许你应该仔细看看How to Use Labels

【讨论】:

  • 我找到了它被画两次的原因。 super.paintComponent (g); 就像我说的,我是菜鸟。 label.setSize 和 setLocation 什么也没做。
  • @JohnPicco 亲爱的上帝,不!画两次的原因是g.drawImage!!您必须始终致电super.paintComponent 以保持油漆链的完整性!
  • “就像我说的,我是菜鸟。label.setSize 和 setLocation 什么也没做” - 你不应该使用它们。 JLabel 将根据图标和文本属性计算它的首选大小,布局管理器将使用此信息来确定如何最好地布局组件。见Laying Out Components Within a Container
  • 感谢您的回复。我一定会阅读这些页面。我阅读了这条线并按照howTo所说的做了,它也有效。我的问题解决了。 :)
  • 不要使用paintComponentJLabel 可以在没有你帮助的情况下显示图像。您可以通过JLabel 本身在组件的可用空间范围内为图标(和文本)的垂直和水平位置指定锚点(LEFT、RIGHT、TOP、BOTTOM、CENTER)。
【解决方案2】:

我对cmets没有名气,所以我回答。

问题是,中心的图像是你创建时的JLabel图像

Jlabel imageLabel = new JLabel(**image**)

只需创建这个没有像这样的图像

JLabel imageLabel = new JLabel(){...}

【讨论】:

  • 不!不要覆盖 paintComponentJLabel 来显示图像,JLabel 已经在没有你帮助的情况下显示图像
  • “如果您知道更简单的方法来调整标签的大小和位置” - 使用适当的布局管理器
【解决方案3】:

只需删除paintComponent 方法。您已经将图像添加到标签中。

并且你应该尽量避免使用你不理解的代码,或者在询问之前尝试了解正在发生的事情,尽量不要说:

我不知道它是如何工作的或为什么会工作,但确实如此。

这不是一个好的编程习惯。

【讨论】:

    猜你喜欢
    • 2011-01-30
    • 1970-01-01
    • 2022-01-23
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2013-02-11
    • 2014-08-14
    • 2016-02-16
    相关资源
    最近更新 更多