Java Platform, Standard Editionトラブルシューティング・ガイド
目次      

10.7 フォーカス・イベント

この項では、次に示すフォーカス・イベントに関連する問題のトラブルシューティングについて説明します。

10.7.1 フォーカス・イベントをトレースする方法

フォーカスの問題をトラブルシューティングするには、フォーカス・イベントをトレースできます。例10-5に示すように、フォーカス・リスナーをツールキットに追加することでこれを行うことができます。

ここでSystem.errストリームが使用されているのは、出力のバッファリングが行われないからです。

なお、フォーカス・イベントの正しい順序は次のとおりです。

  • フォーカスを失うコンポーネントのFOCUS_LOST

  • フォーカスを失うトップ・レベルのWINDOW_LOST_FOCUS

  • アクティブ状態を失うトップ・レベルのWINDOW_DEACTIVATED

  • アクティブ・ウィンドウになるトップ・レベルのWINDOW_ACTIVATED

  • フォーカスされたウィンドウになるトップ・レベルのWINDOW_GAINED_FOCUS

  • フォーカスを得るコンポーネントのFOCUS_GAINED

フォーカスされたウィンドウ内のコンポーネント間でフォーカスが移動する場合は、FOCUS_LOSTイベントとFOCUS_GAINEDイベントのみが生成されるはずです。同じ所有者が所有するウィンドウ間や、所有されるウィンドウとその所有者の間でフォーカスが移動する場合は、次のイベントが生成されるはずです。

  • FOCUS_LOST

  • WINDOW_LOST_FOCUS

  • WINDOW_GAINED_FOCUS

  • FOCUS_GAINED

注意: フォーカスまたはアクティベーションを失うイベントが最初に来る必要があります。

10.7.2 ネイティブ・フォーカス・システム

時折、ネイティブ・プラット・フォームが原因で問題が発生することがあります。これをチェックするには、フォーカスに関係するネイティブ・イベントを調査します。フォーカス対象のウィンドウがアクティブ化され、フォーカス対象のコンポーネントがネイティブ・フォーカス・イベントを受け取ることを確認してください。

Windowsプラットフォームのネイティブ・フォーカス・イベントは、次のとおりです。

  • WM_ACTIVATE (トップ・レベル用)。WPARAMは、アクティブ化の際はWA_ACTIVE、非アクティブ化の際はWA_INACTIVEになります。

  • WM_SETFOCUSおよびWM_KILLFOCUS (コンポーネント用)。

Windowsプラットフォームでは、合成フォーカスという概念が実装されています。つまり、フォーカス所有者コンポーネントはそのフォーカス可能状態をエミュレートするだけですが、実際のネイティブ・フォーカスはフォーカス・プロキシ・コンポーネントに設定されます。このコンポーネントは、キーとインプット・メソッドのネイティブ・メッセージを受け取り、それらをフォーカス所有者にディスパッチします。JDK7より前は、フォーカス・プロキシ・コンポーネントはフレーム/ダイアログ内の専用の非表示の子コンポーネントでした。最新のJDKリリースでは、フレーム/ダイアログ自体がフォーカス・プロキシとして機能します。現在は、所有されるウィンドウ内のコンポーネントだけでなく、すべての子コンポーネントのフォーカス・プロキシとしても機能します。単純なウィンドウは、ネイティブ・フォーカスを受け取ることは決してなく、その所有者のフォーカス・プロキシに依存します。ユーザーがこのメカニズムを意識することはありませんが、デバッグ時には考慮に入れるべきです。

Oracle SolarisおよびLinuxオペレーティング・システム上のXToolkitでは、AWT自体がフォーカスを管理できるフォーカス・モデルを使用しています。このモデルでは、ウィンドウ・マネージャが直接トップレベル・ウィンドウに入力フォーカスを設定することはなく、代わりにWM_TAKE_FOCUSクライアント・メッセージのみを送信することで、フォーカスを設定すべきであることを示します。その後、トップレベル・ウィンドウへのフォーカス設定が可能な場合は、その設定がAWTによって明示的に行われます。

注意: ただし、Xサーバーおよび一部のウィンドウ・マネージャは、ウィンドウにフォーカス・イベントを送信することがあります。ただし、そのようなイベントはすべてAWTによって破棄されます。

トップ・レベル内のコンポーネントがフォーカスを得ても、AWTはフォーカス・イベントの階層チェーンを生成しません。さらに、コンポーネント自体にマップされたネイティブ・ウィンドウがネイティブ・フォーカス・イベントを取得することはありません。Oracle SolarisおよびLinuxプラットフォームではWindowsプラットフォームと同じく、AWTはフォーカス・プロキシ・メカニズムを使用します。したがって、コンポーネントのフォーカスはフォーカス・イベントの合成によって設定され、不可視のフォーカス・プロキシがネイティブ・フォーカスを保持します。

Windowオブジェクト(FrameオブジェクトでもDialogオブジェクトでもない)にマップされたネイティブ・ウィンドウには、override-redirectフラグが設定されます。したがって、ウィンドウ・マネージャはそのウィンドウに対し、フォーカス移動に関して通知しません。このウィンドウでフォーカスが要求されるのは、マウス・クリックへの応答としてだけです。このウィンドウはネイティブ・フォーカス・イベントを一切受け取りません。したがって、トレース可能なイベントは、フレームまたはダイアログ上のFocusInまたはFocusOutイベントだけです。XToolkitでは、フォーカスの主な処理がJavaレベルで発生するため、フォーカスのデバッグがWToolkitの場合よりも単純になります。

10.7.3 Java Plug-inでのフォーカス・システム

アプレットは、EmbeddedFrameの子(ただし直接の子ではない)としてブラウザ内に埋め込まれます。これは、プラグインとの通信機能を備えた特殊なFrameです。アプレットからは、EmbeddedFrameはトップ・レベルの完全なFrameに見えます。

EmbeddedFrameのフォーカスを管理するには、特殊な追加アクションが必要になります。アプレットが最初に起動する際に、EmbeddedFrameはネイティブ・システムによってデフォルトでアクティブ化されません。アクティブ化は、EmbeddedFrameに用意された特殊なAPIをプラグインがトリガーすることによって実行されます。フォーカスがアプレットを離れる際のEmbeddedFrameの非アクティブ化も、合成された方法で行われます。

10.7.4 Xウィンドウ・マネージャでサポートされているフォーカス・モデル

Xウィンドウ・マネージャでサポートされているフォーカス・モデルは、次のとおりです。

  • click-to-focusは一般的に使用されているフォーカス・モデルです。(たとえば、Microsoft Windowsではこのモデルが使用されています。)

  • focus-follows-mouseは、マウスの下にあるウィンドウにフォーカスが移動するフォーカス・モデルです。

Java SE 7のXAWTではfocus-follows-mouseモデルは検出されませんが、これにより、単純なウィンドウ(java.awt.Windowクラスのオブジェクト)で問題が発生します。そのようなウィンドウにはoverride-redirectプロパティが設定されているため、ウィンドウにフォーカスを移動できるのはマウス・ボタンを押した場合のみであり、ウィンドウの上にマウスを移動してもフォーカスは移動しません。回避方法としては、ウィンドウにMouseListenerを設定し、マウスがウィンドウのボーダーを横切ったときにウィンドウへのフォーカスを要求します。

10.7.5 フォーカスのその他の問題

このセクションでは、AWTのフォーカスに関連して発生する可能性のあるいくつかの問題を説明し、その解決方法を提示します。

目次      

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.