前面已經向大家介紹過《用SWT實現MSN風格的下拉框》、《SWT自定義組件之Slider》,現在再編寫一個最常用的自定義組件——Button。
GUI組件要完成的任務有2個,展現與業(yè)務。對于按鈕來說,文本、圖標、邊框、背景屬于展現層,而這些元素在按鈕不同狀態(tài)下會不盡相同,一般來說至少有4種狀態(tài)下的展現:普通、鼠標放在其上、被按下、被禁用,也就是按鈕應該具備這4種狀態(tài)。
下面給出的示例是swing實現的自定義按鈕。
通常swing自定義組件繼承javax.swing.JComponent并重寫protected void paintComponent(Graphics g)方法實現自定義繪制。重寫paintComponent方法時通常要先去掉super.paintComponent(g),因為父方法調用會繪制背景色。不妨先看一下源代碼中的調用過程。
在JComponent.java中paintComponent(Graphics g)方法定義如下:
protected void paintComponent(Graphics g) {
if (ui != null) {
Graphics scratchGraphics = (g == null) ? null : g.create();
try {
ui.update(scratchGraphics, this);
}
finally {
scratchGraphics.dispose();
}
}
}
其中ui的聲明如下
protected transient ComponentUI ui;
然后轉向ComponentUI的update(Graphics g, JComponent c)方法:
public void update(Graphics g, JComponent c) {
if (c.isOpaque()) {
g.setColor(c.getBackground());
g.fillRect(0, 0, c.getWidth(),c.getHeight());
}
paint(g, c);
}
可見如果發(fā)現組件是非透明的,就繪制背景,可以看出swing組件的setBackground方法如何繪制背景的。
一般簡單的自定義組件,你可以只通過重寫paintComponent方法來實現繪制,對于一般的組件這已經足夠。對于自定義按鈕一般的原則是準備4張背景圖對應上述4種狀態(tài),這4種狀態(tài)都可通過鼠標監(jiān)聽來感知,當狀態(tài)改變時,調用repaint()使Button重繪。除了背景,按鈕文本、圖標等的改變一樣也必須調用repaint()來刷新。
然后重要的一點是你必須重寫public Dimension getPreferredSize()來獲得按鈕的最佳尺寸。getPreferredSize方法對于布局管理器來說至關重要,布局管理器會通過getPreferredSize的判斷組件的最佳大小,并進行布局。而對于本范例而言,getPreferredSize的大小只和背景圖片大小有關。
對于業(yè)務,盡量做到前臺界面與后來業(yè)務分離。你可以自定義按鈕動作監(jiān)聽器來實現,本例是沿用swing的Action實現,當鼠標抬起時,構造一個ActionEvent對象,然后交給Action成員的actionPerformed(ActionEvent e)處理。
范例源代碼這里下載