java 设置panel背景图片_java – 如何在JPanel中设置背景图片

可以通过多种方式实现这一目标.

你可以…

放弃

为此目的使用JLabel时可能会导致内容过度溢出,请参阅下面的详细信息

创建JLabel,将图像应用于其图标属性,并将其设置为框架内容窗格.然后,您需要适当地设置布局管理器,因为JLabel没有默认的布局管理器

JFrame frame = ...;

JLabel background = new JLabel(new ImageIcon(ImageIO.read(...)));

frame.setContentPane(background);

frame.setLayout(...);

frame.add(...);

更新完整示例

import java.awt.EventQueue;

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

public class LabelBackground {

public static void main(String[] args) {

new LabelBackground();

}

public LabelBackground() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

}

try {

// Load the background image

BufferedImage img = ImageIO.read(new File("/path/to/your/image/on/disk"));

// Create the frame...

JFrame frame = new JFrame("Testing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// Set the frames content pane to use a JLabel

// whose icon property has been set to use the image

// we just loaded

frame.setContentPane(new JLabel(new ImageIcon(img)));

// Supply a layout manager for the body of the content

frame.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridwidth = GridBagConstraints.REMAINDER;

// Add stuff...

frame.add(new JLabel("Hello world"), gbc);

frame.add(new JLabel("I'm on top"), gbc);

frame.add(new JButton("Clickity-clackity"), gbc);

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

} catch (IOException exp) {

exp.printStackTrace();

}

}

});

}

}

这个问题是JLabel在调整帧大小时不会调整图像大小

警告 – 如果子组件的所需空间超出背景图像的大小,则使用JLabel可能会导致问题,因为JLabel不会根据其内容计算其首选大小,而是基于其图标和文本属性

你可以…

创建一个自定义组件,从JPanel扩展并覆盖它的paintComponent方法,根据需要绘制背景.

这使您能够决定在可用空间更改时图像的最佳缩放比例.虽然有许多方法可以实现,但您应该阅读The Perils of Image.getScaledInstance()以了解它们的优缺点.

这会引发一系列新问题,你想要缩放它们并保持纵横比吗?如果是这样,您是否希望将图像适合可用区域或填充它(因此它将始终覆盖可用空间)?

其他考虑

图像通常最好通过ImageIO API加载,因为它能够加载各种图像,但是当出现问题时也会抛出IOException.

图像的位置也很重要.如果映像在应用程序外部(文件系统的某个位置),则可以使用ImageIO.read(新文件(“/ path / to / image”)).但是,如果图像嵌入在您的应用程序中(例如存储在Jar中),则需要使用更像ImageIO.read(getClass().getResource(“/ path / to / image”))的内容. ..

例如…

此示例演示如何使用充当背景组件的自定义组件.当组件大小超过背景图像的大小时,图像将按比例放大以填充可用内容区域.

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.GridBagConstraints;

import java.awt.GridBagLayout;

import java.awt.HeadlessException;

import java.awt.RenderingHints;

import java.awt.Transparency;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;

public class SimpleBackground {

public static void main(String[] args) {

new SimpleBackground();

}

public SimpleBackground() {

EventQueue.invokeLater(new Runnable() {

@Override

public void run() {

try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

}

try {

BackgroundPane background = new BackgroundPane();

background.setBackground(ImageIO.read(new File("/path/to/your/image/on/your/disk")));

JFrame frame = new JFrame("Testing");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.setContentPane(background);

frame.setLayout(new GridBagLayout());

GridBagConstraints gbc = new GridBagConstraints();

gbc.gridwidth = GridBagConstraints.REMAINDER;

frame.add(new JLabel("Hello world"), gbc);

frame.add(new JLabel("I'm on top"), gbc);

frame.add(new JButton("Clickity-clackity"), gbc);

frame.pack();

frame.setLocationRelativeTo(null);

frame.setVisible(true);

} catch (IOException exp) {

exp.printStackTrace();

}

}

});

}

public class BackgroundPane extends JPanel {

private BufferedImage img;

private BufferedImage scaled;

public BackgroundPane() {

}

@Override

public Dimension getPreferredSize() {

return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());

}

public void setBackground(BufferedImage value) {

if (value != img) {

this.img = value;

repaint();

}

}

@Override

public void invalidate() {

super.invalidate();

if (getWidth() > img.getWidth() || getHeight() > img.getHeight()) {

scaled = getScaledInstanceToFill(img, getSize());

} else {

scaled = img;

}

}

@Override

protected void paintComponent(Graphics g) {

super.paintComponent(g);

if (scaled != null) {

int x = (getWidth() - scaled.getWidth()) / 2;

int y = (getHeight() - scaled.getHeight()) / 2;

g.drawImage(scaled, x, y, this);

}

}

}

public static BufferedImage getScaledInstanceToFill(BufferedImage img, Dimension size) {

double scaleFactor = getScaleFactorToFill(img, size);

return getScaledInstance(img, scaleFactor);

}

public static double getScaleFactorToFill(BufferedImage img, Dimension size) {

double dScale = 1;

if (img != null) {

int imageWidth = img.getWidth();

int imageHeight = img.getHeight();

double dScaleWidth = getScaleFactor(imageWidth, size.width);

double dScaleHeight = getScaleFactor(imageHeight, size.height);

dScale = Math.max(dScaleHeight, dScaleWidth);

}

return dScale;

}

public static double getScaleFactor(int iMasterSize, int iTargetSize) {

double dScale = (double) iTargetSize / (double) iMasterSize;

return dScale;

}

public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {

return getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR, true);

}

protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) {

BufferedImage imgScale = img;

int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);

int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);

// System.out.println("Scale Size = " + iImageWidth + "x" + iImageHeight);

if (dScaleFactor <= 1.0d) {

imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);

} else {

imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality);

}

return imgScale;

}

protected static BufferedImage getScaledDownInstance(BufferedImage img,

int targetWidth,

int targetHeight,

Object hint,

boolean higherQuality) {

int type = (img.getTransparency() == Transparency.OPAQUE)

? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

BufferedImage ret = (BufferedImage) img;

if (targetHeight > 0 || targetWidth > 0) {

int w, h;

if (higherQuality) {

// Use multi-step technique: start with original size, then

// scale down in multiple passes with drawImage()

// until the target size is reached

w = img.getWidth();

h = img.getHeight();

} else {

// Use one-step technique: scale directly from original

// size to target size with a single drawImage() call

w = targetWidth;

h = targetHeight;

}

do {

if (higherQuality && w > targetWidth) {

w /= 2;

if (w < targetWidth) {

w = targetWidth;

}

}

if (higherQuality && h > targetHeight) {

h /= 2;

if (h < targetHeight) {

h = targetHeight;

}

}

BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);

Graphics2D g2 = tmp.createGraphics();

g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);

g2.drawImage(ret, 0, 0, w, h, null);

g2.dispose();

ret = tmp;

} while (w != targetWidth || h != targetHeight);

} else {

ret = new BufferedImage(1, 1, type);

}

return ret;

}

protected static BufferedImage getScaledUpInstance(BufferedImage img,

int targetWidth,

int targetHeight,

Object hint,

boolean higherQuality) {

int type = BufferedImage.TYPE_INT_ARGB;

BufferedImage ret = (BufferedImage) img;

int w, h;

if (higherQuality) {

// Use multi-step technique: start with original size, then

// scale down in multiple passes with drawImage()

// until the target size is reached

w = img.getWidth();

h = img.getHeight();

} else {

// Use one-step technique: scale directly from original

// size to target size with a single drawImage() call

w = targetWidth;

h = targetHeight;

}

do {

if (higherQuality && w < targetWidth) {

w *= 2;

if (w > targetWidth) {

w = targetWidth;

}

}

if (higherQuality && h < targetHeight) {

h *= 2;

if (h > targetHeight) {

h = targetHeight;

}

}

BufferedImage tmp = new BufferedImage(w, h, type);

Graphics2D g2 = tmp.createGraphics();

g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);

g2.drawImage(ret, 0, 0, w, h, null);

g2.dispose();

ret = tmp;

tmp = null;

} while (w != targetWidth || h != targetHeight);

return ret;

}

}

当空间减小时,将图像按比例缩小也是一件简单的事情,但我故意决定将图像保持在最小尺寸.

该示例还利用自定义除法和征服缩放算法,以生成高质量的缩放结果.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值