JFrame背景图片

13

我正在创建一个简单的GUI,想要用一张背景图片(2048 X 2048)填充整个窗口,并在左上角留有一个正方形区域,可以加载偶尔出现的64 X 64图片。如何实现?

我已经知道如何将JFrame设置为固定大小,需要帮助的是如何加载图片。


3
在我提交这篇帖子之前,系统要求我做到这一点。由于我没有发现任何相关的内容,所以继续撰写了这篇文章。如果我的帖子给你带来了不便,那么我希望这是你所面临过的最大不便。 - CCD
2
@Aaron,我已经去过javaranch.com和java-forums.org了。那里很不错。而且他们也很有能力。JavaRanch的座右铭是“JavaRanch,友好对待新手”。我对你在这里提出的问题很感兴趣,点赞。 - Kaydell
1
请查看这个答案,了解如何在您的项目中加载图像。还有@Kaydell,请你也看一下。希望能帮到你 :-) - nIcE cOw
谢谢,我非常感激大家的关注和帮助! - CCD
4个回答

16
这是一个在JFrame中添加背景图片的简单示例:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class BackgroundImageJFrame extends JFrame
{
    JButton b1;
    JLabel l1;

    public BackgroundImageJFrame()
    {
        setTitle("Background Color for JFrame");
        setSize(400,400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

        /*
        One way
        -----------------
        setLayout(new BorderLayout());
        JLabel background=new JLabel(new ImageIcon("C:\\Users\\Computer\\Downloads\\colorful design.png"));
        add(background);
        background.setLayout(new FlowLayout());
        l1=new JLabel("Here is a button");
        b1=new JButton("I am a button");
        background.add(l1);
        background.add(b1);
        */

        // Another way
        setLayout(new BorderLayout());
        setContentPane(new JLabel(new ImageIcon("C:\\Users\\Computer\\Downloads\\colorful design.png")));
        setLayout(new FlowLayout());
        l1=new JLabel("Here is a button");
        b1=new JButton("I am a button");
        add(l1);
        add(b1);
        // Just for refresh :) Not optional!
        setSize(399,399);
        setSize(400,400);
    }

    public static void main(String args[])
    {
        new BackgroundImageJFrame();
    }
} 
  • 点击这里获取更多信息。

所以最后的sesize()会刷新图像? - CCD
@Aaron,我认为与其调用setSize()两次来刷新窗口,不如总是最后调用setVisible(true),这样窗口会被正确绘制。 - Kaydell
1
我研究了Nambi的代码并学到了一些东西,但我改变了代码,我相信它有所改进。这是我的代码版本链接,带有注释:https://gist.github.com/kaydell/6565219 - Kaydell
谢谢,所有这些建议都非常有用,我很感激你们的帮助 :) - CCD
使用pack而不是设置大小,让布局管理器处理它。最后调用setVisible以确保框架在第一次绘制时表现正确。 - MadProgrammer

12
最佳的加载图像方式是通过 ImageIO API
BufferedImage img = ImageIO.read(new File("/path/to/some/image"));

您可以使用多种方法将图像呈现到屏幕上。

如果您不想以任何方式修改图像,则可以使用JLabel。这是最简单的方法...

JLabel background = new JLabel(new ImageIcon(img));

然后,根据需要将其添加到窗口中。如果您需要将组件添加到其中,则可以简单地将标签的布局管理器设置为所需的内容并添加您的组件。

但是,如果您需要更高级的功能,需要以某种方式更改图像或想应用其他效果,则可能需要使用自定义绘图。

首先要注意:永远不要直接在顶层容器(如JFrame)上进行绘制。顶层容器没有双缓冲,因此在重绘之间可能会出现一些闪烁,其他对象位于窗口上,因此更改其绘制过程会带来麻烦并导致其他问题,并且框架具有在可视区域内呈现的边框...

相反,创建一个自定义组件,扩展自类似JPanel的组件。覆盖它的paintComponent方法并将输出呈现给它,例如...

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(img, 0, 0, this);
}

查看执行自定义绘图2D图形以获取更多细节。


我该怎么使用它?我把它放在JLabel中吗? - CCD
@Aaron 这将取决于您的最终目标以及您需要多少控制。是的,JLabel 将是最简单的解决方案。请查看更新。 - MadProgrammer
2
很高兴能够帮助到您 :) - MadProgrammer

5
我使用了与@bott非常相似的方法,但对其进行了一些修改,以使图片不需要调整大小:
BufferedImage img = null;
try {
    img = ImageIO.read(new File("image.jpg"));
} catch (IOException e) {
    e.printStackTrace();
}
Image dimg = img.getScaledInstance(800, 508, Image.SCALE_SMOOTH);
ImageIcon imageIcon = new ImageIcon(dimg);
setContentPane(new JLabel(imageIcon));

每次都能正常工作。您也可以获取jFrame的宽度和高度,并将其代替800和508。


4
您可以做以下事情:
setContentPane(new JLabel(new ImageIcon("resources/taverna.jpg")));

在Jframe类构造函数的第一行,这对我来说很好用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接