本次採用的方法為Override JPanel之paintComponent()方法,即重新繪製Panel,以達到我們所想要的效果。不過,該圖因為固定大小,因此進行縮放時,只會將該圖延展,並不會重複拼貼,所以圖形會有變形之情況發生。另外,在此簡單的介紹paintComponent()之使用方法,並給予範例以供各位參考與學習。
1. 三個繪製元件時之重要方法介紹
Swing中,元件繪製時會執行paint()方法,而讓方法中又包含了三個函式,其會依次調用paintComponent()àpaintBorder()àpaintChildren()這三個方法,以確保子元件能正確地顯示在該元件上。此三個方法分別代表:
a.protected void paintComponent( Graphics g ):繪製元件自身的外觀,以及
b.protected void paintBorder( Graphics g ):繪製元件的邊框
c.protected void paintChildren( Graphics g ):繪製其元件內的所有子元件
2. paintComponent()與JFrame中加入背景圖之關係說明
由於paintComponent()是用在以自身容器自己繪製出自己元件的方法,因此如果只是為了改變本身這個容器中的元件的話,只需要改寫paintComponent()方法即可,而paintBorder()和paintChildren()則採默認值就好。如果還需保留容器中原本的元件,就需調用super.paintComponent(g)。
3. 範例:在此展示一個具有背景圖之視窗,並根據使用者拉大/縮小視窗之情況,動態的延展圖示。
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author Elsa
*/
public class ImgBackgroundDemo extends JFrame{
ImgBackgroundPanel bgPanel = null;
JPanel contentPanel = null;
JLabel label = null;
Image image = null;
public ImgBackgroundDemo(){
// 1.生成元件
bgPanel = new ImgBackgroundPanel();
image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/test2/Res/bgDemo.jpg"));
contentPanel = new JPanel();
label = new JLabel("Hello World!!");
// 2.設置要顯示之資訊與元件
label.setBounds(10, 10, 100, 100); // 設置位置跟寬高
contentPanel.setLayout(null);
contentPanel.setOpaque(false);
contentPanel.add(label);
// 3.設置背景圖panel之設定與加入contentPanel
bgPanel.setImage(image);
bgPanel.setLayout(new java.awt.BorderLayout());
bgPanel.add(contentPanel, BorderLayout.CENTER);
// 4.設置frame之基本設定
this.setTitle("如何在JFrame中加入背景圖");
this.setLayout(new java.awt.BorderLayout());
this.add(bgPanel, BorderLayout.CENTER);
this.setMinimumSize(new java.awt.Dimension(900, 675));
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
public static void main(String[] args) {
new ImgBackgroundDemo();
}
}
▲主程式
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
/**
*
* @author Elsa
*/
public class ImgBackgroundPanel extends JPanel {
private Image image = null;
public ImgBackgroundPanel() {
super();
this.setOpaque(false);
}
public Image getImage() { // 取得image元件
return image;
}
public void setImage(Image image) { // 設置圖片來源
this.image = image;
}
/*
* 繪製背景圖
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if(image!=null){
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
}
}
}
▲Override JPanel之Class
4. 執行結果
▲生成時之樣貌
▲被向右拉動之樣貌
5. paintComponent()與paint()之差異
a. paintComponent()<子>為paint()<父>之中的protected方法,因此在Swing中,因其會依次調用paintComponent()、paintBorder()、paintChildren()三個方法,所以只需重新改寫paintComponent()即可。
b. AWT中元件重繪時會先調用update(Graphics g)以清除之前繪製的內容,之後會再調用paint()方法進行繪製,所以在AWT元件下只需覆寫paint()方法即可。
※小結: 一般情況下,大部分只需重新改寫paintComponent()即可,不過如覆寫paint()方法的話,也可達到同樣的效果,如下之範例程式。
@Override
public void paint(Graphics g){
//super.paint(g);
Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/test2/Res/bgDemo.jpg"));
g.drawImage(image, 0, 0, this.getWidth() , this.getHeight() , this);
super.paintComponents(g); // 呈現效果等同於super.paintChildren(g);
}
參考網址:
http://blog.csdn.net/zgrjkflmkyc/article/details/14002977
http://javapub.iteye.com/blog/763849