gpt4 book ai didi

java - Swing - 带合成器的自定义按钮

转载 作者:行者123 更新时间:2023-11-30 11:50:46 32 4
gpt4 key购买 nike

我正在开发一个将 Synth 用于 UI 的项目,并希望实现一些自定义按钮。这些按钮需要使用合成 XML 设置文件中的样式设置 - 例如不同状态(MOUSE_OVER、PRESSED 等)的字体颜色不同。

我遇到的问题是一些按钮需要有额外的子组件——例如有些需要不止一个标签。我希望子组件采用与标准按钮子组件相同的样式设置。

我觉得我应该能够扩展 JButton 并覆盖/扩展 paintComponent 以调用某些子组件的绘制方法。不过,我对这种方法的某些方面有点不确定:例如传递给 paintComponent 的参数;以及如何确保子组件获得正确的 Synth 样式设置(特别是关于状态)。

旁白:我曾尝试扩展 JPanel,但在使用该方法时遇到了一些困难(参见此处:JPanel states for Synth)。

编辑: 因此,我发现可以将子组件添加到按钮并让它们正确呈现。似乎即使 JButton.getLayout() 返回 null,该按钮也会使用 OverlayLayout,除非您调用 JButton.setLayout()。调用 JButton.setLayout(null) 确实会阻止使用 OverlayLayout,所以这就是我处理布局的方式。

我正在研究几种不同的方法来更新子控件的样式,稍后会报告这些方法。

最佳答案

所以,如果它对其他人有用,我最后采用的方法是:

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) 似乎是最好的。

还有 trashgod 建议的实现自定义 UI 委托(delegate)(扩展 BasicButtonUI)的方法,但如果你采用这种方法,我认为你将不得不重新实现大部分 SynthButtonUI。

关于java - Swing - 带合成器的自定义按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7792054/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com