BeanBox内でフォーカスを得たBeanクラスのプロパティが、プロパティ・シートに どのように表示されるのかを見てみましょう。
まず、そのBeanクラスのBeanInfoが作られます。ここでは、すぐ前で名前の出た IntrospectorクラスのsetTargetPropertyInfo()メソッドが活躍しています。 さらに、このBeanInfoのインスタンスから、PropertyDescriptor の配列を獲得します。 何か、まどろっこしいように感じるかも知れませんが、Beanクラスから、まず、 BeanInfoを作って、それから様々なDescriptorを獲得するというのは、Java Beans プログラミングの基本的なイディオムです。
一つのBeanクラスには、一般に複数のプロパティが存在します。PropertySheetPanelの setTargetメソッドは、ターゲットとなるbeanの一つ一つのPropertyに対して、それ ぞれのsetter / getterメソッドを獲得して、先に見た reflectionの機能を利用して、 getter.invoke(target, args)で、ターゲット上のそのプロパティの値を獲得します。 そして、プロパティの型に対応したeditorをつくって、editor.setValue(value) で、プロパティの値をeditorにセットします。setTagetメソッドは、この処理を、 プロパティの数だけ繰り返します。このように、Java Beansでは、一つのプロパティに 一つのeditorが対応しています。プロパティ・シート全体を、一つのeditorと考える こともできるのですが、正確に言うと、プロパティ・シートは、沢山のeditor達が 集まって出来ているのです。
============================================================================
class PropertySheetPanel extends Panel {
.......
synchronized void setTarget(Object targ) {
........
........
target = targ;
try {
// フォーカスが当てられたbeanクラスから BeanInfoを作成し、
// そのBeanInfoからPropertyDescriptor の配列を獲得する。
BeanInfo bi = Introspector.getBeanInfo(target.getClass());
properties = bi.getPropertyDescriptors();
} catch (IntrospectionException ex) {
........
}
// Propertyの数の分だけ、それぞれの配列を準備する。
editors = new PropertyEditor[properties.length];
values = new Object[properties.length];
........
// adapterは、PropertyChangeListener を実装
EditedAdaptor adaptor = new EditedAdaptor(frame);
// Propertyの数だけ、その値を表示する。
for (int i = 0; i < properties.length; i++) {
.......
Method getter = properties[i].getReadMethod(); // getterの獲得。
Method setter = properties[i].getWriteMethod(); // setterの獲得。
.......
try {
Object args[] = { };
// 注目 !! target上でのgetterの呼び出し。すなわち、値の獲得。
Object value = getter.invoke(target, args);
values[i] = value;
PropertyEditor editor = null;
Class pec = properties[i].getPropertyEditorClass();
if (pec != null) {
try {
// PropertyEditorClassのインスタンスの作成 = editorの作成
editor = (PropertyEditor)pec.newInstance();
} catch (Exception ex) {
}
}
if (editor == null) {
// 駄目なら、別の方法でeditorを作る。
editor = PropertyEditorManager.findEditor(type);
}
editors[i] = editor;
..........
// editorに値を設定する。
editor.setValue(value);
// adaptorは、editorの リスナーになる。
editor.addPropertyChangeListener(adaptor);
..........
} catch (Exception ex) {
..........
}
.......
}
.......
}
.......
}
============================================================================
このsetTargetメソッドは、BeanBox内のあるBeanに新しいフォーカスが置かれた時 に最初に呼び出されて、そのプロパティの値を読み出して PropertySheetを形成 するのが主な仕事ですが、もう一つ、大事な役割を担っています。 それは、後で見る editorでのプロパティの値の変更を、BeanBox内のbeanに反映するための仕掛けを準備 することです。setTargetは、ターゲットとなる一つのbeanに対して、 EditedAdaptorクラスのオブジェクトを一つ用意します。そして、そのbeanに属する 一つ一つのプロパティのeditorが、このadapterオブジェクトを、それぞれの PropertyChangeEvent の Listenerとして登録するようにします。for文の中で、 editor.addPropertyChangeListener(adaptor) が繰り返されているのは、その為です 一つのbeanには複数のeditor達が関連付けられるのですが、これらが集まった同じ PropertySheet上で発生した PropertyChangeEventは、すべて、いったん、このadaptor に集められるということです。