イベントリスナーを登録する

リスト項目を選択したときに発生するイベントに反応するには、リスナーを設定しておきます。それには、次のように、

javax.swing.JList
public void addListSelectionListener(
ListSelectionListener listener)

メソッド addListSelectionListener(ListSelectionListener) を利用します。引数 listener には、インターフェース ListSelectionListener を実現した、任意のリスナーオブジェクトを指定できます。リスナーには、次のメソッドを実現しておく必要があります。


javax.swing.event.ListSelectionListener
void valueChanged(ListSelectionEvent e)

メソッド valueChanged(ListSelectionEvent) は(Swing が提供するフレームワークに沿って)イベント ListSelectionEvent が発生したときに呼び出されます。「ハリウッドの原則」に従って、このメソッドを呼び出すコードを記述する必要はありません。そして、メソッドを定義するときには、発生したイベント e から、必要な情報を獲得できます。

    view = new JList();
view.addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
...

JavaBeans に準拠した Swing には、Jython の便利な機能を適用できます。すると、ここに示した Java 版のコードと同じ効果を得るのは簡単で、次のように、

    view = JList(
valueChanged=paintColor,

キーワード引数 valueChanged= の後に、イベントリスナー(関数/メソッド)を指定するだけです。すると、特定のクラス(実現方法)には依存せず「インターフェースの規定だけに従う」ことが、より明確になります。


このようにすると、キーワード valueChanged= を固定するだけで、仕様変更にも柔軟に対処できるコードが得られます。Java の国境を越えて Jython の世界に入るときには、addListSelectionListener/ListSelectionListener など余分な荷物は捨てて、身軽な旅を堪能できます。この特徴は、他のコンポーネントにも利用できるので、重宝します。
TipsJython では、JavaBeans に準拠したリソースに対して、それを実現するクラスに依存せず、インターフェースの規定に従うだけの、簡潔で見通しの良いコードを記述できます。そのため、仕様変更にも柔軟に対処できます。

例外:TypeError

ここで着目して欲しいのは、Java と違って、メソッドの名前は任意(つまり、valueChanged でなくてもよい)ということです。ただし、次のように、

    def paintColor(e):

イベントを参照する引数 e を宣言するのを忘れないことです。ここで、次のように定義すると、

    def paintColor():    # Boo: (x_x) bad manner

例外 TypeError が発生して、次のエラーメッセージが出力されます。

TypeError: paintColor() too many arguments; expected 0 got 1

これは「引数は必要ない」と定義したのに、実行時に「引数が1つ」渡されたことを意味します。
ハリウッドの原則に従うなら、メソッド paintColor を呼び出すコードを記述する必要はありません(しない権利)が、それが適切に呼び出されるように準備を怠らない(する義務)ことです。
《Tips》バグの正しい飼い方:TypeError が発生したら、実引数/仮引数が整合するか、確認してみることです。


Previous|3/5|Next