torutkのブログ

ソフトウェア・エンジニアのブログ

JavaFXのSwingNodeがJavaFXのイベントをSwingのイベントに変換しているあたり(続)

昨日の日記(id:torutk:20150918)の続きです。

マウスのホイール操作で拡大・縮小するSwingの画像表示コンポーネントをSwingの画面上に貼って動かしたときは、タッチパネルのピンチ操作で拡大・縮小しています。Swingはタッチパネル入力には対応していないので、なぜかな?と思っていました。

そこで、Windows のタッチパネル入力の仕様を調べてみました。MSDNの次のドキュメント
Windows タッチジェスチャの概要」のレガシサポート節に情報がありました。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd940543.aspx

Windowsタッチメッセージに登録していないアプリケーション(RegisterTouchWindow APIを呼んでいない)は、既定のジェスチャハンドラーが次のジェスチャを既存のWindowsメッセージにマップするとあります。

  • パン WM_VSCROLL、WM_HSCROLL
  • プレス アンド ホールド WM_RBUTTONDOWN, WM_RBUTTONUP
  • ズーム WM_MOUSEWHEEL

では、JavaアプリケーションはWindowsタッチメッセージに登録しているかどうかを調べます。
OpenJDK 8uのソースとOpenJavaFXを取得し、RegisterTouchWindow APIを呼んでいる箇所を調べてみると、OpenJDK側にはなく、OpenJavaFX側の次のソースファイルにありました。

  • modules/graphics/src/main/native-glass/win/ViewContainer.cpp
void ViewContainer::InitManipProcessor(HWND hwnd)
{
    if (IS_WIN7) {
        ::RegisterTouchWindow(hwnd, TWF_WANTPALM);

IS_WIN7は次のdefineです。

#define IS_WIN7 IS_WINVER_ATLEAST(6, 1)

ということで、JavaFXを使わずにSwingだけでアプリケーションを作った場合は、タッチパネルを持つPC上で動かして、タッチパネル上でピンチ操作をすると、Windows OSからアプリケーションへWindowsメッセージWM_MOUSEWHEELが通知されます。
Swing上ではMouseWheelEventで拡大・縮小するように作っているコンポーネントはタッチパネル上でのピンチ操作に応答している状態になります。

一方、JavaFXを使ったアプリケーションでは、タッチパネルのイベント(WM_TOUCH)がWindows OSからアプリケーションへ通知されるので、その中でイベントをどう扱っているかを調べる必要があります。

続きは今日か後日か・・・