如何在Java Swing GUI的框架中将图像设置为背景?

13

我用Java的Swing创建了一个GUI。现在我需要将一张sample.jpeg图片设置为我放置组件的框架的背景。如何操作?

8个回答

22
JPanel 中,没有“背景图片”的概念,因此需要编写自己的方法来实现这种特性。其中一种方法是重写 paintComponent 方法,在每次刷新 JPanel 时绘制背景图像。
例如,可以创建一个 JPanel 的子类,并添加一个字段来保存背景图像,然后重写 paintComponent 方法:
public class JPanelWithBackground extends JPanel {

  private Image backgroundImage;

  // Some code to initialize the background image.
  // Here, we use the constructor to load the image. This
  // can vary depending on the use case of the panel.
  public JPanelWithBackground(String fileName) throws IOException {
    backgroundImage = ImageIO.read(new File(fileName));
  }

  public void paintComponent(Graphics g) {
    super.paintComponent(g);

    // Draw the background image.
    g.drawImage(backgroundImage, 0, 0, this);
  }
}

(以上代码未经过测试。)

下面的代码可以用来将JPanelWithBackground添加到一个JFrame中:

JFrame f = new JFrame();
f.getContentPane().add(new JPanelWithBackground("sample.jpeg"));
在这个例子中,使用了ImageIO.read(File)方法来读取外部JPEG文件。

2
这并没有完全回答问题。它在面板上放置了一个背景图像,但然后只是将面板插入到正常布局中。问题是如何在其他组件后面设置框架的背景。 - Boann
如果您将null作为您的ImageObserver,会引起问题吗? - georgiaboy82

5
这可以通过用绘制图像的JPanel替换框架的内容面板来轻松完成:
try {
    final Image backgroundImage = javax.imageio.ImageIO.read(new File(...));
    setContentPane(new JPanel(new BorderLayout()) {
        @Override public void paintComponent(Graphics g) {
            g.drawImage(backgroundImage, 0, 0, null);
        }
    });
} catch (IOException e) {
    throw new RuntimeException(e);
}

这个例子还将面板的布局设置为边界布局,以匹配默认内容窗格布局。

(如果你无法看到图片,可能需要在其他一些组件上调用setOpaque(false)来使其透明,这样就可以看到背景了。)


3

这篇背景面板文章根据你的需求提供了不同的实现方式。


2
也许最简单的方法是添加一张图片,缩放它,并将它设置为JFrame/JPanel(在我这里是JPanel),但要记得只有在添加了其他子组件之后才将其“添加”到容器中。请参考以下图片:enter image description here
    ImageIcon background=new ImageIcon("D:\\FeedbackSystem\\src\\images\\background.jpg");
    Image img=background.getImage();
    Image temp=img.getScaledInstance(500,600,Image.SCALE_SMOOTH);
    background=new ImageIcon(temp);
    JLabel back=new JLabel(background);
    back.setLayout(null);
    back.setBounds(0,0,500,600);


1

这里有另一种快速方法,无需使用额外的面板。

JFrame f = new JFrame("stackoverflow") { 
  private Image backgroundImage = ImageIO.read(new File("background.jpg"));
  public void paint( Graphics g ) { 
    super.paint(g);
    g.drawImage(backgroundImage, 0, 0, null);
  }
};

2
我发现这种技术无法正常工作。有时图像会覆盖子组件,有时在不应该的情况下被普通框架背景遮盖。 - Boann

1

如果您正在使用NetBeans,您可以向框架添加JLabel,并通过属性将其图标更改为您的图像并删除文本。然后通过导航器将JLabel移动到JFrame或任何内容窗格的底部。


我无法使其工作,因为当你添加一个面板时,背景图像会被推开。 - S. Mitchell
1
框架的布局必须采用绝对布局。 - ThilinaMD

0
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();
 }
 }

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