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 に集められるということです。