【摘要】
本文詣在展示如何在Swing中引入 NinePatch技術(shù)(早期有文章里中文譯作九格圖,暫且這么叫吧^_^,但此術(shù)非傳統(tǒng)移動手機(jī)上的功能布局——九格圖哦)。
【準(zhǔn)備篇】
Q:何為 NinePatch技術(shù)?
A:說簡單點(diǎn),就是用于對圖片據(jù)屏幕大小進(jìn)行自動拉伸的技術(shù)。更準(zhǔn)確的介紹詳見此文:http://www.yixieshi.com/ucd/9142.html。
NinePatch技術(shù)本身雖微不足道,但它對于 UI定制開發(fā)來說無疑是相當(dāng)有價值的。也可直接看官方指南:http://developer.android.com/guide/developing/tools/draw9patch.html。
Q:NinePatch對Swing意味著什么?
A:利用NinePatch技術(shù),比如:你在美化Swing的按鈕UI時,再也不用根據(jù)不同的按鈕大小準(zhǔn)備不同的圖片了,一張圖片解決不同按鈕按各自大小自動拉伸填充的問題,多么神奇!
當(dāng)然,如果你對 程序比較熟,或者說對 程序外觀定制比較熟的話,你將會更清楚這一點(diǎn)——Swing的外觀定制能力將會因此變的無比靈活和強(qiáng)大,
很多不可能將成為現(xiàn)實(shí)。Android程序的外觀定制其實(shí)有點(diǎn)Java標(biāo)準(zhǔn)平臺換膚技術(shù)Synth的影子,但顯然,這個聰名的小改進(jìn),使得 外觀定制比Swing更容易、更靈活。
Q:從何處獲得NinePatch技術(shù)呢?
A:NinePatch技術(shù)的核心只有3到4個類,拿過來用就可以了,源碼地址可以在此鏈接找到:
http://www.java2s.com/Open-Source/Android/android-core/platform-sdk/com.android.ninepatch.htm,我打好的包稍
后可以在附件里下載哦。
【準(zhǔn)備好.9.png圖片】
本圖片將使用NinePatch技術(shù)作為演示代碼中的一JPanel背景進(jìn)行自動填充之用,用不同的2張圖是為了方便進(jìn)行效果展示:

【測試代碼】

package jb2011.t;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.io.InputStream;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import com.android.ninepatch.NinePatch;
/**
* 本類用于測試從Android中引入的NinePatch(九格圖)技術(shù)的可行性.
*
* @author jb2011@163.com
* @version 1.0
*/
class Test extends JPanel
{
//NinePatch作為全局對象,提高性能
private NinePatch mPatch;
public Test()
{
super (new BorderLayout());
//*** 關(guān)鍵代碼:讀取9格圖 START
try{
InputStream stream = this .getClass().getResourceAsStream(
// "content_bg2.9.png"
"content_bg3.9.png"
);
mPatch = NinePatch.load(stream, true /* is9Patch*/, false /* convert */);
}
catch (Exception e){
e.printStackTrace();
}
//*** 關(guān)鍵代碼:讀取9格圖 END
//加入一個面板,用于演示
JPanel p = new JPanel();
p.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
//該面板設(shè)置成背景透明
p.setOpaque(false);
this.add(p);
//加入演示組件
p.add(new JButton("JButton 1"));
p.add(new JButton("JButton 2"));
p.add(new JButton("JButton 3"));
p.add(new JButton("JButton 4"));
}
/**
* 重寫父類方法,以便實(shí)現(xiàn)自定義背景的繪制.
*/
@Override protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
Rectangle clip = g2.getClipBounds(); // 有點(diǎn)小問題,要用(0, 0, getWidth(), getHeight()),否則每次繪制的clip都不一樣而導(dǎo)致異常現(xiàn)象.
//*** 關(guān)鍵代碼:使用9格圖 START
//使用9格圖繪制面板的背景
mPatch.draw(g2, clip.x, clip.y, clip.width, clip.height);
//*** 關(guān)鍵代碼:使用9格圖 END
}
public static void main(final String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setContentPane(new JPanel(new BorderLayout()));
((JPanel)frame.getContentPane()).setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
frame.getContentPane().add(new Test(), BorderLayout.CENTER);
frame.setSize(300,250);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

【運(yùn)行效果圖】

【附件下載】
測試代碼完整Eclipse3.5.2工程(含NinePatch的jar包哦):
http://files.cnblogs.com/jb2011/jb2011blog_testNinePatch.rar
================================================================================
【最后再啰嗦幾句】
潛水了很多年,得益于許多無私網(wǎng)友的奉獻(xiàn),越發(fā)覺得很有必要與人分享一些東西。接下來將陸續(xù)寫出“Swing整容”系列文章,
希望對需要的人有用,但因水平確實(shí)有限,不喜者還請勿噴,多謝。
有人說,Swing很丑,這話沒錯,但Swing真的沒救了?答案當(dāng)然是否定的。接下來的文章將會與Swing的L&F有關(guān),謝謝關(guān)注。
“民工甲”的“Swing三刀”系列文章給了我最近一次Swing美化工作的部分靈感,非常感謝作者的無私,文章地址是:
http://joshuaxiao.iteye.com/blog/707514。“WilliamChen”的Swing技術(shù)文章也是相當(dāng)不錯,可惜多年不更新了,有興趣的朋
友可以去圍觀哦,http://blog.sina.com.cn/swingjava。
From: http://www.cnblogs.com/jb2011/archive/2012/05/02/2479002.html
@import url(http://www.shnenglu.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);