したがって、それが他の誰かに役立つ場合に備えて、私が最終的に取ったアプローチは次のとおりです。
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 の多くを再実装する必要があると思います。