JavaBeans 是可視化構建工具可操作的可重用軟體組件。其核心規範涵蓋四類屬性、事件模型、持久化機制與設計時資訊(BeanInfo),支援拖拉式應用開發。
| 類型 | 特徵 | 方法模式 | 用途 |
|---|---|---|---|
| Simple | 單一值 | getX()/setX()、isX()(boolean) | 一般屬性 |
| Indexed | 陣列/列表 | getX(int)/setX(int, T)、getX()/setX(T[]) | 集合屬性 |
| Bound | 變更通知 | + add/removePropertyChangeListener | 屬性同步、UI 綁定 |
| Constrained | 變更可否決 | + add/removeVetoableChangeListener、拋出 PropertyVetoException | 受限屬性驗證 |
public class SimpleBean {
private String text = "Hello";
public String getText() { return text; }
public void setText(String text) { this.text = text; }
}
public class IndexedBean {
private int[] data = {1,2,3,4,5};
public int[] getData() { return data; }
public void setData(int[] data) { this.data = data; }
public int getData(int i) { return data[i]; }
public void setData(int i, int val) { data[i] = val; }
}
public class BoundBean {
private String value;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public String getValue() { return value; }
public void setValue(String newValue) {
String old = this.value;
this.value = newValue;
pcs.firePropertyChange("value", old, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener l) { pcs.addPropertyChangeListener(l); }
public void removePropertyChangeListener(PropertyChangeListener l) { pcs.removePropertyChangeListener(l); }
}
public class ConstrainedBean {
private int price;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private VetoableChangeSupport vcs = new VetoableChangeSupport(this);
public void setPrice(int newPrice) throws PropertyVetoException {
int old = this.price;
vcs.fireVetoableChange("price", old, newPrice); // 可能拋出 PropertyVetoException
this.price = newPrice;
pcs.firePropertyChange("price", old, newPrice);
}
// ... listener 註冊/移除方法
}
java.util.EventObject,類名以 Event 結尾java.util.EventListener,類名以 Listener 結尾,定義處理方法add<Listener>Listener/remove<Listener>Listener 註冊方法// 事件物件
public class TemperatureEvent extends EventObject {
private double celsius;
public TemperatureEvent(Object source, double celsius) { super(source); this.celsius = celsius; }
public double getCelsius() { return celsius; }
}
// 監聽者介面
public interface TemperatureListener extends EventListener {
void temperatureChanged(TemperatureEvent e);
}
// 事件源
public class Thermometer {
private List listeners = new CopyOnWriteArrayList<>();
public void addTemperatureListener(TemperatureListener l) { listeners.add(l); }
public void removeTemperatureListener(TemperatureListener l) { listeners.remove(l); }
private void fireTemperatureChanged(double c) {
TemperatureEvent e = new TemperatureEvent(this, c);
for (TemperatureListener l : listeners) l.temperatureChanged(e);
}
}
當監聽者介面含多方法,或需過濾/轉發事件時,引入適配器類:
public class TemperatureAdapter implements TemperatureListener {
private TemperatureListener target;
public TemperatureAdapter(TemperatureListener target) { this.target = target; }
public void temperatureChanged(TemperatureEvent e) {
if (e.getCelsius() > 100) target.temperatureChanged(e); // 過濾條件
}
}
java.io.Serializable 介面transient/static 欄位自動序列化MANIFEST.MF 標記 JavaBeans 類別public class MyBeanBeanInfo extends SimpleBeanInfo {
@Override
public PropertyDescriptor[] getPropertyDescriptors() {
try {
PropertyDescriptor pd = new PropertyDescriptor("text", MyBean.class);
pd.setPropertyEditorClass(TextEditor.class); // 自定義屬性編輯器
pd.setBound(true); // 標記為 Bound 屬性
return new PropertyDescriptor[]{pd};
} catch (IntrospectionException e) { return null; }
}
@Override
public EventSetDescriptor[] getEventSetDescriptors() { ... }
@Override
public MethodDescriptor[] getMethodDescriptors() { ... }
@Override
public Image getIcon(int iconKind) { ... } // 16x16/32x32 圖示
}
| 介面/類 | 用途 |
|---|---|
Customizer | 複雜屬性的自定義對話框/面板,實現 java.beans.Customizer |
PropertyEditor | 單一屬性的專用編輯器(下拉選單、顏色選擇器等),繼承 PropertyEditorSupport |
BeanInfo | 描述 Bean 的屬性/事件/方法/圖示,供構建工具顯示 |
getX/setX、isX(boolean)addXListener/removeXListener、fireXXEvent、監聽者:XListenerXBeanInfo、Customizer:XCustomizer、Editor:XEditor