因此,如果它对其他人有用,这是我最后采用的方法:
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) 将样式设置从按钮复制到子组件。方法(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 委托(扩展BasicButtonUI
)的方法,但是如果您采用该方法,我认为您将不得不重新实现 SynthButtonUI 的大部分内容。