2012-04-03 23 views
1

私は通常のパネルとウィジェットを含むJFrameを持っています。私はそのJFrameのglassPaneとして使用しているJPanelを持っています。私は、キーボードフォーカスのトラバースを、表示されているときにglassPaneのコンポーネントに制限できるようにしたいと考えています。スイング:キーボードのフォーカストラバーサルを特定のウィジェットに限定する

私の問題は、バックグラウンドスレッドがプロセスを起動して、進行中のダイアログが表示され、その後消えてしまい、glassPane内のウィジェットからフォーカスを盗みますが、その下のウィジェットに戻すという事実によって、私のglassPane。

私は、JFrameのフォーカストラバーサルポリシーを、glassPaneのフォーカスのみを許可するように設定しようとしましたが、効果がないようです。 (たぶん私はそれを間違ってやったのでしょうか?)

助けていただければ幸いです。

+0

あなたのアプリケーションは非常に複雑であると思われます。好奇心の中で、どのような種類のコンポーネントをガラス板に表示していますか、なぜガラス板ですか? –

+0

glassPaneには、スクロールするTextPane、JCheckBox、およびJButtonがあります。これはEULAの表示に使用されており、ユーザーはアプリケーションを使用する前にその条件に同意する必要があります。私のユーザーはモーダルJDialogを使用したときに不平を言ったので、私は代替案を検討しています。 –

+0

私はそれを間違って実行したかもしれません - おそらく、あなたのコードを見ることなく伝えるのは難しいでしょう:-)つまり、glasspane _is_ trickyを管理すると(カスタムftpはmouseEventsの責任を負いませんのであまり役に立ちません) JLayer(jdk7の場合)またはJXLayer(jdk6の場合)を使用することを検討することもできます。 – kleopatra

答えて

3

私のコメントで述べたように、私はおそらくJ/X/Layerに行くだろうが、確かにカスタムFTPがあなたの文脈で唯一の欠けている部分であるなら、解決策がある。

コンポーネントをフォーカストラバーサルから除外するには、カスタムFTPのacceptメソッドでコンポーネントを拒否します。以下は、glassPaneが表示されている場合にglassPaneの子ではないすべてのコンポーネントを拒否する例です(注:これはあまり単純すぎるため、直接の子のみを処理するため、現実のコードは、ガラスペインかどうか)

public static class FTP extends LayoutFocusTraversalPolicy { 

    @Override 
    protected boolean accept(Component comp) { 
     JFrame window = (JFrame) SwingUtilities.windowForComponent(comp); 
     if (hasVisibleGlassPane(window)) { 
      return comp.getParent() == window.getGlassPane(); 
     } 
     return super.accept(comp); 
    } 

    private boolean hasVisibleGlassPane(JFrame window) { 
     return window != null && window.getGlassPane() != null 
       && window.getGlassPane().isVisible(); 
    } 

} 
+0

よかった、ありがとう。私はFocusTraversalPolicyのサブクラスを調べることを完全に忘れて、それを直接拡張しました。記録のために私は別の解決策に行くことになったが、これは実際に質問されたように答えている。 –

2

glassPaneが表示されている間に、無視する(または最悪の場合は)すべてのコンポーネントについて、無視するJFrameで.setFocusable(false)を呼び出してみてください。

3

私はあなたの問題を解決することを信じているように私のコメントの答えを作るつもりです:CardLayoutは、単に窓ガラスやダイアログではなく、意見を交換するために使用する

おそらくより良いオプションがありますこの状況は、ガラスペインの使用に最も適していないように思われるからです。 CardLayoutを使用している場合は、別のクルージングの副作用を修正するために、(ガラスのペインを使用する予定のものではないものを使用して)クルージング(フォーカストラバーサルのフィドル)を出す必要はありません。

もしあなたがそれに慣れていないなら、CardLayoutはGUIのコンポーネントを簡単に入れ替えることができますし、ユーザーが主要なプログラム状態から別のプログラム状態に移行するときに発生する複雑なGUIを保持するJPanelを交換することがよくあります。私はそれがあなたの目的には完璧だと思うし、あなたの焦点問題を心配することを防ぐでしょう。

0

私はクライアントと議論したとき、彼は私に同じ要件を与えました。そこで私はJLayerとLayeredPaneをプロジェクトに使用することに決めました。これらのコンポーネントをすべてシンプルなソリューションとして実装しました。これはコードに実装されているので、プロジェクトに役立つかもしれません。

public YourConstructor() { 
    yes.addFocusListener(new FocusAdapter() { 
     public void focusLost(FocusEvent fe) { 
      if (!no.hasFocus()) { 
       no.requestFocusInWindow(); 
      } 
     } 
    }); 

    no.addFocusListener(new FocusAdapter() { 
     public void focusLost(FocusEvent fe) { 
      if (!yes.hasFocus()) { 
       yes.requestFocusInWindow(); 
      } 
     } 
    }); 
} 

@Override 
public void setVisible(boolean visibility) { 
    super.setVisible(visibility); 
    if (visibility) { 
     yes.requestFocusInWindow(); 
    } 
} 
関連する問題