簡單地說,heavyweight component 在實做上會使用 OS or window system 的 native 元件,比如 java.awt.Button 在成為 displayable 時會讓 OS/window system 建立 native button(一種 child window),Java Button object 以 peer 來與這個 native button(window) 聯繫,native button(window) 建立後其操作是由 OS/window system 來管理,繪製與訊息的接收由 window system 派送給 native button。
Lightweight component 如 javax.swing.JButton,其 instance 只是在記憶體中的一堆資料,他透過 UI framework 的協助,以 paint method 來繪製其外型,仰賴其 parent container 提供一些訊息派送給他來與外界互動,如果 parent container 也是 lightweight component,此 container 本身也仰賴其 parent container,追溯到最上層一定有一個 heavyweight container 存在(比如 JFrame,他是 heavyweight component),擔起與 OS/window system 橋接的任務。如果不實作 lightweight component 的 paint method 與所有處理 event 的 method,那麼即使把這個 lightweight component 放進 displayable container 裡,將沒有辦法從鍵盤滑鼠的操作偵測出這個 lightweight component 是否存在 container 裡,因為見不著也摸不到這個 lightweight component(沒有互動),精明的人可能會想到觀察 container 所使用的 layout manager 的排版行為推敲是否有一個元件在某位置上,這倒是可以。
下面一個簡單的例子,同樣地我不實作 AWT button 與 swing JButton 的 paint method 與 processMouseEvent method,執行後可以觀察到,heavyweight Button 跟我有沒有 override 此二 method 似乎沒有關連(其實有,CButton 不會發出 mouse event 給 MouseListener),可以見到一個很正常的按鈕(正確顯示 label),也可以 click 而發出 ActionEvent。反觀 lightweight JButton,看不見了。若把 overriding paint method 移除,可以見到 JButton 外觀了,但是用滑鼠 click 之,沒有反應也沒有發出 ActionEvent。
package com.jsptw.j2se;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class HeavyWeight extends JFrame {
public static void main(String[] args)
{
JFrame frm = new HeavyWeight("heavyweight V.S. lightweight");
frm.setDefaultCloseOperation(EXIT_ON_CLOSE);
frm.setSize(300, 300);
frm.show();
}
public HeavyWeight(String title)
{
super(title);
initComponents();
}
private void initComponents()
{
Button cb = new CButton("Heavyweight button");
cb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("AWT button clicked");
}
});
getContentPane().add(cb, BorderLayout.SOUTH);
JButton xb = new XButton("Lightweight button");
xb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.out.println("swing button clicked");
}
});
getContentPane().add(xb, BorderLayout.NORTH);
}
}
package com.jsptw.j2se;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
class CButton extends Button {
public CButton(String label) throws HeadlessException
{
super(label);
}
public void paint(Graphics g)
{
}
protected void processMouseEvent(MouseEvent e)
{
}
}
package com.jsptw.j2se;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Graphics;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
class XButton extends JButton {
public XButton(String text)
{
super(text);
}
public void paint(Graphics g)
{
}
protected void processMouseEvent(MouseEvent e)
{
}
}