前の関連記事:Calc(53)追加できるリスナー一覧: その5
セルをマウスでクリックするとselectionChanged()メソッドが4回も発火する
シートのセルをシングルクリックするとコントローラーに追加したリスナーのメソッドがこのように発火しました。
XSelectionChangeListenerのselectionChanged()メソッドが4回も発火しています。
すでに選択してあるセルをクリックするとmousePressed()とmouseReleased()の間のselectionChanged()が発火しなくなりました。
本来はすでに選択されているセルをクリックしたときはselectionChanged()は発火しないのが正しいと思われるので、mouseReleased()の後の3回のselectionChanged()が正しくない動作とわかります。
Windows10でやってみても同じ結果でした。
マウスをドラッグして複数のセルを選択すると何回もselectionChanged()が発火する
マウスでSheet1のB19:D23を選択状態にしました。
selectionChanged()メソッドが9回も発火しています。
mousePressed()とmouseReleased()の間でselectionChanged()が7回発火していますが、この回数は一定せず4回とか6回とかバラバラでした。
選択するセルの数に依存するかと思いましたそうでもありませんでした。
mouseReleased()の後にselectionChanged()が発火する回数は常に2回でした。
selectionChanged()が発火した時点のコントローラーから選択状態のセル範囲を取得してみると次のように変化していました。
Selection: Sheet1.B19
Selection: Sheet1.B19:B20
Selection: Sheet1.B19:B20
Selection: Sheet1.B19:C21
Selection: Sheet1.B19:C22
Selection: Sheet1.B19:D22
Selection: Sheet1.B19:D23
mouseReleased()の後にselectionChanged()が発火するときは常にSheet2.B19:D23になっていました。
マウスドラッグをしている間の状態でselectionChanged()が発火しているとわかりましたが、選択範囲が変化していないのに発火しているのはどうも納得ができません。
Shiftキー押しながら矢印キーで複数セルを選択したときは当然選択セルが変化するごとにselectionChanged()が発火していました。
Shiftキーを押しながらマウスで選択セル範囲を決定したときはmouseReleased()の前はマウスをクリックした回数だけしかselectionChanged()は発火しませんでした。
しかしmouseReleased()はドラッグして選択した時と同様にselectionChanged()が2回発火していました。
selectionChanged()メソッドを使うときはLibreOffice5(115)イベントが呼ばれる順を調べるマクロでやったようにグローバル変数のフラグを用意するなどして複数回の発火に備えないといけないようです。
1つのセルに対して処理したいだけなら、selectionChanged()は使わずmousePressed()でセルを取得すればよいですが、複数セルを選択中にその時点の選択範囲のセルに対してしょるしたいときはselectionChanged()を使わないといけません。
(2018.1.15追記。mouseReased()のあともselectionChanged()が発火するのでそうはいきませんでした。)
セルをダブルクリックした時
ダブルクリックしたときはselectionChanged()メソッドが全部で5回発火しています。
mousePressed()→selectionChanged()→mouseRealeased()→selectionChanged()→selectionChanged()→selectionChanged()
ここまではシングルクリックと同じです。
このときmouseRealeased()の引数に入っているEnhancedMouseEvent StructのClickCountは1になっています。
ダブルクリック目はmousePressed()→mouseRealeased()→selectionChanged()になっています。
このときのEnhancedMouseEvent StructのClickCountは2です。
ダウブルクリックするときに複数セルを選択することはなそうなので、1回目のmousePressed()の時にフラグを立てといてselectionChanged()を1回実行してmouseRealeased()でフラグを倒して、EnhancedMouseEvent Structの2以上の時はフラグを立てないようにすればselectionChanged()は1回の実行で済みます。
(2018.5.14追記。selectionChanged()メソッドの引数からeventobject.Source.getSelection().getRangeAddress()でセル範囲アドレスをキャッシュしておいて、それが変化したときのみ実行するようにする方法もあります。)
セルを右クリックした時
mousePressed()のEnhancedMouseEvent StructのButtonsは右ボタンを表す2になっていましたが、PopupTriggerはFalseになっていました。
続いてselectionChanged()が発火していますが、mouseReleased()は発火しませんでしいた。
既に選択されたセル範囲を右クリックしたときはmousePressed()しか発火しませんでした。
EnhancedMouseEvent StructのTargetはセルの選択範囲に関係なく常にクリックしたセルが入っているので、選択範囲を取得したいときはコントローラーからgetSelection()などを使わないといけません。
行や列全体を選択した時
列インデックスをクリックして列全体を選択するとselectionChanged()が5回も発火しました。
その代わりマウスでクリックしているのにXEnhancedMouseClickHandlerのメソッドが発火していません。
selectionChanged()の1回目の発火の時はその時のコントローラーからクリック前の選択範囲が取得されていました。
2回目の発火の時はクリックしたセルの先頭のセルが取得できました。
3回目以降はクリックした通り列全体の範囲が取得できていました。
行全体を選択したときも同様でした。
selectionChanged()はなかなか使い方が難しそうです。
シートタブでシートを変更した時
マウスでシートタブのSheet2のタブをクリックしてSheet1から切り替えました。
これもXEnhancedMouseClickHandlerのメソッドは発火しません。
またselectionChanged()が4回も発火しています。
前半の2回のselectionChanged()には切り替え前のSheet1での選択範囲がコントローラーから取得されていて、後半の2回には切り替え後の選択範囲が入っていました。
最後にactivateSpreadsheetChanged()が発火しています。
このactivateSpreadsheetChanged()の引数のActivationEvent StructのActiveSheetからシート、Sourceからコントローラーを取得できるのでそこから選択範囲が取得できます。
ということはシートの切り替えの時はselectionChanged()は利用する必要はなさそうです。
ちなみに複数のシートタブを選択したときはどのリスナーも発火しませんでした。
0 件のコメント:
コメントを投稿