3

UIにSynthを使用してプロジェクトに取り組んでおり、いくつかのカスタムボタンを実装したいと考えています。ボタンは、シンセXML設定ファイルのスタイル設定を使用する必要があります。たとえば、状態(MOUSE_OVER、PRESSEDなど)ごとに異なるフォントの色です。

私が立ち往生している問題は、いくつかのボタンに追加のサブコンポーネントが必要なことです。たとえば、いくつかは複数のラベルが必要です。サブコンポーネントに、標準のボタンサブコンポーネントと同じスタイル設定を適用させたい。

一部の子コンポーネントの描画メソッドを呼び出すために、拡張JButtonおよびオーバーライド/拡張​​できるようにする必要があると感じています。paintComponentただし、そのアプローチのいくつかの側面については少しわかりません。たとえば、どのパラメーターに渡すかpaintComponent。サブコンポーネントが正しいシンセスタイル設定(特に状態)を確実に取得する方法。

余談ですが、私は拡張を試みJPanelましたが、そのアプローチでいくつかの問題に遭遇しました(ここを参照:SynthのJPanel状態)。

編集:それで、ボタンにサブコンポーネントを追加して、それらを正しくレンダリングさせることが可能であることを発見しました。JButton.getLayout()nullを返しても、OverlayLayoutを呼び出さない限り、ボタンはunを使用するようJButton.setLayout()です。呼び出すJButton.setLayout(null)と、OverlayLayoutが使用されなくなります。そのため、このようにレイアウトを処理しています。

子コントロールのスタイルを更新するためのいくつかの異なるアプローチを検討しています。後でそれらについて報告します。

4

1 に答える 1

1

したがって、それが他の誰かに役立つ場合に備えて、私が最終的に取ったアプローチは次のとおりです。

class CustomButton extends JButton {
    CustomButton() {
        // ... normal button init

        // Enable absolute positioning of sub-components.
        setLayout(null);

        updateStyles();

        getModel().addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                updateStyles();
            }
        });
    }

    private void updateStyles() {
        // See below for implementation.
    }

    private int getSynthComponentState() {
        // This is basically a copy of SynthButtonUI.getComponentState(JComponent)
        int state = SynthConstants.ENABLED;
        if (!isEnabled()) {
            state = SynthConstants.DISABLED;
        }

        if (model.isPressed()) {
            if (model.isArmed()) {
                state = SynthConstants.PRESSED;
            } else {
                state = SynthConstants.MOUSE_OVER;
            }
        }
        if (model.isRollover()) {
            state |= SynthConstants.MOUSE_OVER;
        }
        if (model.isSelected()) {
            state |= SynthConstants.SELECTED;
        }
        if (isFocusOwner() && isFocusPainted()) {
            state |= SynthConstants.FOCUSED;
        }
        if (isDefaultButton()) {
            state |= SynthConstants.DEFAULT;
        }
        return state;
    }
}

updateStyles() メソッドを実装する方法として、(A) 別の名前付きスタイルを使用するようにコンポーネントの名前を変更する、または (B) ボタンからサブコンポーネントにスタイル設定をコピーするという 2 つの方法を見つけました。アプローチ (A) は非常に単純ですが、アプローチ (B) は次のように機能します。

private void updateStyles() {
    SynthStyle ss = SynthLookAndFeel.getStyle(this, Region.BUTTON);
    SynthContext sc = new SynthContext(this, Region.BUTTON, ss, getSynthComponentState());

    for (Component c : getComponents()) {
        c.setFont(ss.getFont(sc));
        c.setBackground(ss.getColor(sc, ColorType.BACKGROUND));
        c.setForeground(ss.getColor(sc, ColorType.FOREGROUND));
        // ... and so on if you have other style elements to be changed.
    }
}

異なる状態ごとに複数のスタイル設定を変更する場合は、おそらくアプローチ (A) の方が適していますが、多くの異なる状態に対して異なるスタイルを使用している場合は扱いにくくなる可能性があります。いくつかのスタイル設定のみを変更する場合 (たとえば、私の場合、少なくとも今のところ色だけを気にしている場合)、アプローチ (B) が最善のようです。

カスタム UI デリゲート (extending ) を実装するという Trashgod によって提案されたアプローチもありBasicButtonUIますが、そのルートを取る場合は、SynthButtonUI の多くを再実装する必要があると思います。

于 2011-10-19T08:19:14.867 に答える