[Java] JFrame JPanel 設背景圖片
在 JFrame 和 JPanel 中雖然有背景的設定 .setBackground() 但參數只能是顏色 Color.COLORNAME 或 new Color(r,g,b)。如果背景要放圖片,可能會想到這樣:
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JFrameBackgroundDemo extends JFrame{
JFrameBackgroundDemo(){
JPanel myPanel = new JPanel();
// 用 Dimension 和 JFrame 的 .pack() 可保證大小正確
myPanel.setPreferredSize(new Dimension(800,600));
JLabel bgLabel = new JLabel();
bgLabel.setIcon(new ImageIcon("img/background.png"));
bgLabel.setLocation(0, 0);
bgLabel.setVisible(true);
myPanel.add(bgLabel);
this.add(myPanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
}
}
背景圖片路徑是 img/ 下的 background.png。想法是用一個 JLabel 使用該圖片然後定位在 (0, 0) 但這不是好辦法,因為他會推開其他 JComponent 而且當其他有動作時會被 JLabel 蓋住(我對 javax 的上下層邏輯實在無法理解),所以改用別的辦法,參考自 StackOverflow : Simplest way to set image as JPanel background,重寫了 JPanel 中的 paintComponent() 方法:
import java.awt.Dimension;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class JFrameBackgroundDemo extends JFrame{
JFrameBackgroundDemo(){
JPanel myPanel = new JPanel() {
@Override // 重寫 paintComponent() 方法
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(new ImageIcon("img/background.png").getImage(), 0, 0, null);
} // 此處的background.png 是 800*600 大小的圖片,定位在 (0,0)
};
myPanel.setPreferredSize(new Dimension(800,600));
this.add(myPanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
}
}
在實現 JPanel 時重寫 paintComponent() 利用 .drawImage 功能來畫背景,這樣的做法不會干擾其他 JComponent 物件。
另外加入 Timer 和實作 ActionListener 可做出背景圖片的移動:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class MovingBackgroundDemo extends JFrame implements ActionListener{
int bgPositionX = 0;
Timer bgTimer;
MovingBackgroundDemo(){
bgTimer = new Timer(30, this); // 計時器30毫秒動一次
bgTimer.start();
JPanel myPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(new ImageIcon("img/background_double.png").getImage(), bgPositionX, 0, null);
} // background_double.png 是兩倍寬度的背景,定位由 bgPositionX 決定
};
myPanel.setPreferredSize(new Dimension(800,600));
this.add(myPanel);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.pack();
}
@Override
public void actionPerformed(ActionEvent e) {
bgPositionX -= 2; // 每30毫秒讓背景圖片向左移動2px
if(bgPositionX < -800) { // 當左移到極限時重置
bgPositionX = 0;
}
repaint();
}
}
留言
張貼留言