2011年06月04日

(Java)JListに登録したListSelectionListenerのvalueChangedメソッドが二度実行されてしまう

といいつつ(前記事参照)、突如JavaのJListについてです。
実は以前L----Noteの作成を始める前に勉強を兼ねてJavaで同じような構造のものを試作したのですが、その時JListを使い、リストの項目を選択すると二回ListSelectionListenerのvalueChangedメソッドが実行されるという現象に悩まされました。
結局完全な解決をみないまま放棄してしまったのですが、今回再度デスクトップ版の作成にチャレンジして、またも苦しむ羽目になりました。
以前よりは少しは技術が向上しているのではないかと自分の中で期待が高まりましたがあえなく玉砕しかけました。
しかし、最後の最後で怪しいながらも動くようにはなったので、それをここに書き込んでおきたいと思います。
実際情報を探しても1件くらいしか見つからないことを考えると、根本的なところで間違っているような気はしますし、今後訂正するかも知れませんが。


まず最初にJListにaddListSelectionListenerして、ListSelectionListenerをimplementsしたクラスを以下のように書きました。

    private class MyListSelectionListener implements ListSelectionListener{
    // List項目を選択した時の処理
@Override
public void valueChanged(ListSelectionEvent e) {
JList tmp = (JList)e.getSource();
String selectedItem = (String)tmp.getSelectedValue();
int position = (int)tmp.getSelectedIndex();

myListSelectedMethod(selectedItem,position); // 行いたい処理
}
    }

これで実行し、println文で動きを見てみると、1回クリックしただけなのに、実際に行いたいメソッドが2回呼び出されてしまいます。そのため、二回目の実行時の値が有効になって思わぬ動きをしてしまいます。
上記の処理も参考サイトなどに書かれている通りに書いたのですが、valueChangedが二度実行されることについては触れていません。
ListSelectionEventのリファレンスを読んで見ても、最初のインデックスと最後のインデックスが返る、というようなことが書かれているのですが、自分にとっては意味不明。シングルセレクションにしているのに値が二つとは何故?

以前にも同じものしか見つかりませんでしたが、ググると、if(e.getValueIsAdjusting()){}で囲うことで二回実行を避けられるという情報が見つかります。今回ももう一度試して見ましたが、やはり少なくとも僕のコードでは思ったように動きませんでした。
しかし、今回は最終的にListSelectionEventからではなく、JListから直接選択している値が取得できることが分かったので、コードを書き換えて実行。
println文で値を見ていると、二度実行は避けられませんでしたが、二度目に-1が返っていることが分かりました。
そのため、-1の返り値を無視することにして、以下のように書き直しました。

public void valueChanged(ListSelectionEvent e) {
String selectedItem = (String)list.getSelectedValue(); // listはJListのインスタンス
int position = (int)list.getSelectedIndex();

if(position != -1) myListSelectedMethod(selectedItem,position);
}

なお、原理はいまだに理解できていません。(笑)
汎用的に使えるのかどうか多少疑問を感じないではないです。
またそもそもListSelectionListenerの使い方が間違っているような気はしますが、とりあえずこれで今のところは動いたということで、同様の情報を探している方の参考になればと思いました。
(でも、このサイトが検索上位に上がって、人目につくのはあまり好ましくないですけどね(笑))

posted by 白虹 at 10:25| Comment(0) | TrackBack(0) | Java
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

この記事へのトラックバックURL
http://blog.sakura.ne.jp/tb/45708683

この記事へのトラックバック