4

状態を共有する2つ以上のを作成したいJButton。つまり、マウスボタンをどちらかの上に押すとJButton、両方が押された状態(「武装」)としてレンダリングされるか、チェックボックスの場合は両方が同時にオン/オフになります。

ユーザーには、両方のボタンが同じボタンであるかのように表示され、階層内の複数の場所に表示される必要があります(実際には、Swingではこれは許可されていません)。

ButtonModel1つを作成し、両方のボタンに同じモデルを割り当てることで、途中まで到達できます。これにより、武装/チェック/選択された状態などが同期されます。

ただし、この方法でボタン間で共有されない顕著な効果の1つはフォーカスです。一方のボタンをクリックすると、そのボタンにフォーカスが与えられ(ボタン内の長方形で示されます)、もう一方のボタンから削除されます。どちらかのボタンが実際にフォーカスを持っているときはいつでも、両方のボタンがフォーカスされているかのようにレンダリングしたいと思います。

これを行うためのクリーンな方法はありますか?

理想的には、選択したルックアンドフィールから独立していることを望みます。

編集:共有に関する別の問題を発見しましたButtonModel。ボタンの1つがフォーカスを失うと、モデルのプロパティarmedとプロパティがに設定されます。これは処理後に発生するため、最初のボタンにフォーカスがあるときに2番目のボタンを押すと、もう一度押すまで押された状態にはなりません。pressedfalsemousePressed

4

3 に答える 3

3

これが私がしたことです:

  • JButton新しいクラスで拡張するSharedFocusButton
  • SharedFocusButtonオーバーライドhasFocusgetModelおよびpaintBorder.
  • JButton.paintBorder(Graphics)またはが実行されているときButtonUI.update(Component, Graphics)に、 の動作を一時的に変更して、グループ内のいずれかのボタンにフォーカスがある場合hasFocusに戻るようにします。また、プロキシを返すようtrueに の動作を一時的に変更します(それ以外の場合は shared を返します) 。getModelButtonModelButtonModel
  • プロキシは、イベントの処理中にまたはプロパティの値をに変更することを拒否することを除いてButtonModel、デフォルトの shared のように動作します。ButtonModelarmedpressedfalsefocusLost
  • focusGainedおよびを処理focusLostし、グループ内のすべてのボタンを強制的に再描画します (各ボタンにはフォーカス イベントを処理する独自の UI があるため、これは自動的には行われません)。

残りの問題:キーがフォーカスを同じグループ内の 1 つのボタンから別のボタンに転送しない
ように、おそらくフォーカス トラバーサルを変更する必要があります。Tab

于 2010-02-03T12:48:09.400 に答える
3

2 つのボタンに同じ ButtonModel を使用することで、非常にうまくいきました。

フォーカスに関する問題について説明します。答えはノーL&Fです。不可知論者の方法はありません。オーバーライドBasicButtonUI(またはButtonUI使用しているもの) し、フォーカス描画ロジックをオーバーライドする必要があります。

于 2010-02-03T04:01:09.970 に答える
1

テキスト、リスナーなどはすでに整理されていると思います。

BasicButtonUI の paint メソッドに行くと、特定の描画を行う前にボタンにフォーカスがあるかどうかを実際にチェックしていることがわかります。したがって、フォーカスされた 2 つのコンポーネントを同時に持つことができない限り、私が考える唯一の方法は、他のボタンの UI を使用してペイントすることです。

両方のボタンが FocusButton である必要があり、互いに setButton を呼び出す必要があります。とりわけ、null チェックを追加する必要はありません。

public class FocusButton extends JButton {
    private JButton btn;

    public FocusButton() {
        addFocusListener(new FocusListener() {
            public void focusGained(FocusEvent e) {
                // Other button seems to repaint when focus is gained anyway
            }

            public void focusLost(FocusEvent e) {
                btn.repaint();
            }
        });
    }

    public void setButton(JButton btn) {
        this.btn = btn;
    }

    public void paint(Graphics g) {
        if (!btn.hasFocus()) {
            super.paint(g);
        } else {
            btn.paint(g);
        }
    }
}

編集:ボタンのサイズが同じでない場合、これはうまく機能しません。また、異なるテキストが必要な場合は明らかにまったく機能しません。

于 2010-02-03T03:58:03.660 に答える