Java - 具有背景图像和正常功能的JPanel

时间:2013-05-16 20:30:07

标签: java swing jpanel background-image paintcomponent

我一直在四处寻找并致力于让JPanel能够拥有图像背景。我知道有很多信息可以说明这一点(example 1example 2)。这些都不是我正在寻找的。

我正在寻找的是一种只需添加功能或在JPanel上设置背景图像的功能,同时保留其他所有内容的方法。我现在遇到的问题是我有一些扩展JPanel的类,当我更改它们以扩展我的新ImagePanel类时,构造函数失败(显然,参数不同)。我有一个这样的文件的构造函数super( new BorderLayout() );,我到目前为止能够使它运行的唯一方法是抛弃布局或背景图像。我不能让两者一起工作。

这是最近的绝望尝试:

import java.awt.*;
import javax.swing.JPanel;

class ImagePanel extends JPanel {

  private Image img;

  public ImagePanel(Image img, LayoutManager layout) {
    this.img = img;
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
    super.setLayout(layout);
  }

  public void paintComponent(Graphics g) {
    g.drawImage(img, 0, 0, null);
  }

}

如果有人能帮助我,或者指出我正在寻找的东西,那就太好了。我不需要任何超级疯狂的功能,如背景缩放或类似的东西。我只想将图像作为背景,并以其他方式保持其功能。

感谢。

2 个答案:

答案 0 :(得分:2)

施法者不能在死者之间转移。也就是说,如果扩展一个类并且不提供与父类相同的构造函数,那么就不能使用这些构造函数签名。

例如,在您的示例源代码中,您无法调用new ImagePane(new BorderLayout()),因为ImagePane没有与该签名匹配的构造函数,尽管JPanel确实如此。< / p>

这很重要,因为它允许您让用户使用特定的初始化路径,这可能是您的班级版本所独有的。

如果要重新使用父类中的可用构造函数,则需要在自己的类中提供这些签名,或者使用所需参数调用super(...);

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import javax.swing.JPanel;

public class ImagePanel extends JPanel {

    private Image img;

    public ImagePanel(LayoutManager layout) {
        super(layout);
    }

    public ImagePanel(Image img, LayoutManager layout) {
        this(layout);
        this.img = img;
    }

    public Image getImage() {
        return img;
    }

    public void setImage(Image value) {
        if (img != value) {
            Image old = img;
            img = value;
            firePropertyChange("image", old, img);
            revalidate();
        }
    }

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

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }
    }

}

我还建议您仔细阅读Performing Custom Painting,了解有关自定义绘画的详细信息......

答案 1 :(得分:1)

如果您愿意接受建议,可以考虑使用JLayeredPane

这些容器有层,每层都能够存储组件 因此,您可以在底层使用JPanelJLabel,并在底层使用背景图片,并在另一个JPanel上放置更高层。

如果您想坚持使用ImagePanel,也可以致电super.paintComponent

class ImagePanel extends JPanel {
        ...

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