1

通常のパネルとウィジェットの品揃えを含む JFrame があり、その JFrame の glassPane として使用している JPanel があります。GlassPane が表示されているときに、キーボード フォーカス トラバーサルをそのコンポーネントに制限できるようにしたいと考えています。

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

JFrame のフォーカス トラバーサル ポリシーを、glassPane のフォーカスのみを許可するポリシーに設定しようとしましたが、効果がないように見えました。(もしかして私のやり方が悪かった?)

どんな助けでも大歓迎です。

4

5 に答える 5

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();
    }

}
于 2012-04-04T09:27:42.233 に答える
3

それがあなたの問題の解決策であると信じているので、私は私のコメントを答えにするつもりです:

ガラス ペインやダイアログではなく、 CardLayoutを使用して単純にビューを交換することをお勧めします。CardLayout を使用する場合は、別のクラッジの副作用を修正するためにクラッジ (フォーカス トラバーサルをいじる) を考え出す必要はありません (使用を意図していないものにガラス板を使用します)。

慣れていない場合は、CardLayout を使用すると、GUI 内のコンポーネントを簡単に交換できます。また、ユーザーがある主要なプログラム状態から別の状態に移行するときに発生する複雑な GUI を保持する JPanel を交換するためによく使用されます。それはあなたの目的にぴったりで、フォーカスの問題を心配する必要がなくなると思います.

于 2012-04-03T21:35:14.807 に答える
2

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

于 2012-04-03T20:56:49.797 に答える
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();
    }
}
于 2013-04-23T17:00:08.443 に答える