[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(); } }
留言
張貼留言