【问题标题】:Image is not being added as background in Java Swing [closed]图像未在 Java Swing 中添加为背景 [关闭]
【发布时间】:2021-03-13 15:26:12
【问题描述】:

我有这段代码,我正在尝试在背景中添加图片显示作为墙纸。我用这个stackoverflow post 作为参考,但它没有用。我的图像被添加到面板中,尽管不是作为背景。可能是什么问题?

旁注,.setLocation() 也不会更新按钮的位置。提前致谢!

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.sql.*;
  
  
class APP extends JPanel
{
    JFrame frame = new JFrame();
    JPanel panel;
  
    class ImagePanel extends JComponent {
        Image image;
        public ImagePanel(Image image) {
            this.image = image;
        }
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 100, 25, this);
        }
    }
  
    public APP(){
  
        JLabel picLabel = new JLabel();
  
  
        try {
            BufferedImage image = ImageIO.read(getClass().getResource("login_bg.jpg"));
            this.setContentPane(new ImagePanel(image));
            picLabel = new JLabel(new ImageIcon(image));
            //picLabel.setBounds(100, 25, 843, 568);
        } catch (IOException e){
            e.printStackTrace();
        }
 
  
        panel = new JPanel();                    // used to do padding like in HTML
        panel.setBorder(BorderFactory.createEmptyBorder(50, 350, 300, 350));
        panel.setLayout(null));
        panel.add(picLabel);
   
   
        frame.add(panel, BorderLayout.CENTER);
        frame.getContentPane();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Drone Delivery");
        frame.pack();
        frame.setVisible(true);
   
    }
   
}

【问题讨论】:

  • pastebin 因为它有 100 多行 - 帖子是正确的minimal reproducible example。我们对您的整个申请不感兴趣。创建一个框架只需要几行代码,而创建一个带有图像的 JLabel 或在面板上对图像进行自定义绘制应该只需要几行代码。在尝试解决问题时简化问题..
  • @camickr 是的,你说得对,我刚刚更新了代码以提高可读性
  • 代码应该贴在这里。我们应该能够复制/粘贴/编译/测试并看到所描述的问题。
  • 仍然不是 MRE。 1)代码不会编译。我们无权访问GhostText 类。 MigLayout 是第 3 方布局,与所述问题无关。 2) ActionListener 代码与所述问题无关。正如我在第一条评论中所说,您需要一个 JFrame,您将自定义组件作为背景添加到框架中。然后将单个组件添加到后台组件中。人们总是在测试之前编写整个应用程序,这总是让我感到惊讶。提示:1) 扩展 JPanel,而不是 JComponent。 2)然后您需要设置背景组件的布局管理器。
  • 你是想要上课的人 - 不。您被要求提供minimal reproducible example。只有与问题直接相关的代码才包含在“MRE”中。其他一切都无关紧要。我给了你一些代码示例来简化问题。

标签: java image swing


【解决方案1】:

仍然不是 MRE,但会更好一些,所以我会提出更多建议:

  1. 没有调用代码的 main() 方法
  2. 无需向面板添加 5 个组件。一个组件将演示该问题。
  3. 事实上,您仍然根本不需要面板,因为您还没有创建带有背景图像的 JFrame。

代码的基本问题:

  1. 您的逻辑试图用您绘制图像的自定义类替换默认内容窗格。正如我在上面的“提示”中所建议的那样,如果您想要背景图像,那么 a) 组件应该扩展 JPanel,并且 b) 您需要在类的构造函数中将布局管理器设置为 BorderLayouut。现在您可以将子组件添加到面板了。

  2. 您有两个 JFrame 实例。您的类扩展了 JFrame,并在构造函数中创建了 JFrame 的新实例。不要扩展 JFrame。

  3. 您的 ImagePanel 需要添加到构造函数中创建的“框架”中。

因此,解决方案的第一部分就是让这个逻辑正常工作。这就是您所需要的 JFrame,其中您的 ImagePanel 添加为框架的内容窗格。

然后你继续下一步。

我的图片正在添加到面板中,尽管不是作为背景。

实际上,由于上​​述原因,它没有被添加为背景。您看到的是包含 ImageIcon 的“JLabel”。摆脱标签。

//frame.getContentPane().setLayout(new FlowLayout());

不需要上面的语句。如果你按照我上面的提示,你应该已经在类的构造函数中设置了“ImagePanel”的布局管理器。

frame.add(panel, BorderLayout.CENTER);

试试看会发生什么。您的面板将覆盖图像。

现在试试:

    frame.add(panel, BorderLayout.PAGE_START);

您应该会看到框架顶部的组件。

您还可以添加:

panel.setOpaque(false);

您将在组件下方看到图像。

【讨论】:

  • 我按照您的要求将代码更新为 MRE(我希望这次我做到了),其次,设置 BorederLayout 会很好,但它不会按照我的意愿布置组件,所以我做了setLayout(null); 尝试了您的建议(更改了代码,扩展了 JPanel 而不是 JFrame,注释了一些行),而我在框架中得到的只是我的文本字段(我没有包含在上面的代码中,但这是另一个主题) 并且图像仍未缓冲到帧中
  • 我放弃了。 App 类不需要扩展任何东西。不需要 JLabel。不需要JPanel。在继续向背景图像添加组件的下一步之前,您完全错过了仅显示背景图像的建议。如果您需要我的更多帮助,那么:1) 删除这个问题 2) 通过发布一个关于“如何显示背景图像”的新问题重新开始,并包括只做一件事的 minimal reproducible example
  • 已有答案时如何删除问题?如果您是模组,请这样做
【解决方案2】:

你的代码有很多问题,还有很多坏习惯。

  1. setLocation() 只有在禁用 Layoutmanager 后才会产生永久效果。 使用panel.add(create_btn);,您将需要一个带有 LayoutManager 的面板,该面板不对组件进行任何布局。我不知道 MigLayout,但正如 LayoutManagers 通常所做的那样,它们会布置组件。因此,每当任何更改使 MigLayout 对面板的组件进行布局时,之前通过 setSize/setLocation/setBounds 等进行的任何手动更改都会丢失。

  2. 你重新使用了变量“create_btn”,你实际上并没有将第一个添加到任何面板,因此它不会出现。最佳实践:

  • 不要重复使用变量
  • 使用 final 在字段中初始化尽可能多的组件。这不包括初始化引发异常的任何组件;但是,它们仍应尽快初始化并在可能的情况下最终确定
  1. 看起来您正在混淆 Class APP 和您创建的独立框架 (frame = new JFrame();)。您将图像添加到 APP,但您从不显示框架 APP。相反,在内部,您创建第二个框架“框架”,不要向其添加任何图片/标签,然后显示它。所以难怪图像不会显示,因为它在框架“APP”中永远不会显示。

/更新: 如果您想自己定位所有项目,只需添加行panel.setLayout(null);

【讨论】:

  • 我会让我的代码更好,但图片实际上显示在框架中,而不是作为背景。我会修复建议并更新
  • 查看我关于 setLayout(null) 的更新
  • 我做了尽可能多的更改,但最后我做不到。将 Manager Layout 设置为 null 时,它只会使框架变得如此之小,并且不会添加面板组件。谢谢回答,我很感激
  • 确实如此,但您必须手动设置帧大小和所有组件位置/边界
【解决方案3】:

我建议你使用JLabel。这个组件可以有布局和组件,也可以有背景图片(使用setIcon(ImageIcon icon))。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 2011-01-14
    • 2014-09-30
    • 2014-08-31
    • 2012-07-14
    相关资源
    最近更新 更多