【问题标题】:Add an Background image to a Panel将背景图像添加到面板
【发布时间】:2012-11-27 08:05:26
【问题描述】:

我有一个JPanel,我想添加一张图片作为它的背景。我该怎么做?

frame = new JFrame("Some frame");
panel1 = new JPanel();
panel1.setBorder(new EmptyBorder(5, 5, 5, 5));
// NEED TO ADD AN IMAGE TO THIS PANEL

panel1.setLayout(cardlayout);
frame.getContentPane().add(panel1);

frame.setLocationByPlatform(true);
frame.setVisible(true);

我需要将图像添加到panel,我该怎么做?

更新 1

    panel1 = new JPanel()
    {
    private static final long serialVersionUID = 1L;

    @Override
    public void paintComponent(Graphics g)
    {

        g.drawImage(Toolkit.getDefaultToolkit().createImage("1.jpg"), 0, 0, null);
    }
};

【问题讨论】:

  • 在更新中,我看到您忘记在覆盖的paintComponent 方法中调用super.paintComponent(g);,这可能是一个主要问题(即使是在paintComponent 中提取图像之外的问题)。被覆盖的方法最好首先调用它们的super
  • 查看这些答案 herethis one 以获取一些示例
  • @DavidKroukamp 我尝试添加 super.paintComponent(g); 但它仍然没有向 Jpanel 添加图像
  • 是 1.jpg 与您的 jar 位于同一目录中吗?还是捆绑的?
  • 如果它包含在 jar 中并且与执行类相同,请尝试:Image img = ImageIO.read(getClass().getResourceAsStream("1.jpg")); 否则您必须执行“/packagename/1.jpg”(注意任何句点(@987654333 packagename 中的 @) 必须替换为 /)

标签: java image swing jpanel paintcomponent


【解决方案1】:

您遇到了资源定位问题。

如果找不到资源,Toolkit#createImage 可能会返回一个空图像。

我建议你改用ImageIO API,它支持更广泛的图像格式,但如果找不到或无法加载图像也会抛出异常。

加载图像的方式还取决于图像的位置。

如果图像存在于文件系统中,您可以简单地使用File 对象引用,如果图像是嵌入式资源(在您的应用程序中),则需要使用Class#getResource 来获取URL给它。

public class TestGraphics {

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

    public TestGraphics() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setContentPane(new PaintTest());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class PaintTest extends JPanel {

        private BufferedImage image;

        public PaintTest() {

            setLayout(new BorderLayout());
            try {
                // Use this if the image exists within the file system
                image = ImageIO.read(new File("/path/to/image/imageName.png"));
                // Use this if the image is an embedded resource
//                image = ImageIO.read(getClass().getResource("/path/to/resource/imageName.png"));
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? super.getPreferredSize() : new Dimension (image.getWidth(), image.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image != null) {
                int x = (getWidth() - image.getWidth()) / 2;
                int y = (getHeight()- image.getHeight()) / 2;
                g.drawImage(image, x, y, this);
            }
        }

    }

}

【讨论】:

  • +1 不错的建议和示例。我一直使用ImageIO#read,但从未想过Toolkit#createImage 会有所不同,很高兴知道。
【解决方案2】:

您需要覆盖JPanel 的方法paintComponent(Graphics g) 并在Graphics 对象g 上使用drawImage(),如this example


另外,通过@trashgod查看这两个示例:

  1. example
  2. example

【讨论】:

  • 另外,我会使用ImageIO 来加载图片
  • @sharonHwk Toolkit.getDefaultToolkit().createImage("1.jpg") 可能会返回 null 结果或如果您尝试引用的图像不存在则为空图像。确保图像存在并且可以从应用程序的上下文中引用
  • @MadProgrammer "createImage("1.jpg") 可能会返回null 结果" 这就是为什么我更喜欢ImageIO.read(..) - 当它被破坏时,它会提供更多有用的信息。 :)
  • @AndrewThompson 这里没有参数
猜你喜欢
  • 1970-01-01
  • 2015-04-06
  • 2015-11-06
  • 2012-04-09
  • 2011-06-01
  • 2017-01-14
  • 2013-12-16
  • 1970-01-01
相关资源
最近更新 更多