close

本次採用的方法為Override JPanelpaintComponent()方法,即重新繪製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 JPanelClass

 

4. 執行結果

ImgBackgroundFromLabelDemo_1.png

生成時之樣貌

 

ImgBackgroundDemo_2.png

被向右拉動之樣貌

 

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

 

 

 

arrow
arrow
    創作者介紹
    創作者 Elsa 的頭像
    Elsa

    Elsaの程式學習筆記

    Elsa 發表在 痞客邦 留言(0) 人氣()