方案一:自適應拉伸填充(推薦)
public class ImagePanel extends JPanel {
private final Image image;
public ImagePanel(Image img) {
this.image = img;
// 可選:setPreferredSize(new Dimension(img.getWidth(null), img.getHeight(null)));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); // 清屏、繪製子組件
if (image != null) {
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
}
}
// 使用
Image img = Toolkit.getDefaultToolkit().getImage("bg.jpg");
JPanel panel = new ImagePanel(img);
frame.setContentPane(panel);
方案二:圖片平鋪重複(適用紋理/小圖)
public class TiledPanel extends JPanel {
private final Image image;
public TiledPanel(Image img) { this.image = img; setOpaque(false); }
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) return;
int iw = image.getWidth(this), ih = image.getHeight(this);
if (iw <= 0 || ih <= 0) return; // 圖片未加載完成
for (int x = 0; x < getWidth(); x += iw) {
for (int y = 0; y < getHeight(); y += ih) {
g.drawImage(image, x, y, this);
}
}
}
}
圖片加載方式對比
| 方式 | 代碼 | 特點 |
| Toolkit | Toolkit.getDefaultToolkit().getImage(path) | 異步加載、支援 URL、舊 API |
| ImageIO | ImageIO.read(new File(path)) | 同步加載、異常可捕獲、現代 API |
| ClassLoader | getClass().getResource("/img/bg.jpg") | 載入 classpath 資源、打包 JAR 可用 |
完整可運行範例
public class BackgroundDemo extends JFrame {
public BackgroundDemo() {
setTitle("背景圖片示範");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(600, 400);
setLocationRelativeTo(null);
// 方式:ClassLoader 讀取資源
URL imgUrl = getClass().getResource("/background.jpg");
Image img = Toolkit.getDefaultToolkit().getImage(imgUrl);
// 使用拉伸面板
setContentPane(new ImagePanel(img));
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(BackgroundDemo::new);
}
}
常見問題
- 圖片不顯示:確認路徑正確、圖片已加載完成(`MediaTracker` 或 `ImageIO.read` 同步等待)
- 調整大小後背景不更新:`paintComponent` 會自動重繪,無需手動處理
- 元件遮擋背景:子元件 `setOpaque(false)` 可透出背景
- 高 DPI 模糊:使用多解析度圖片或 `Graphics2D` 縮放提示 `RenderingHints.VALUE_INTERPOLATION_BICUBIC`