我想创建两个或多个共享状态的JButton
,即当鼠标按钮被按下JButton
时,两者都呈现为郁闷(也称为“武装”),或者如果它们是复选框,同时选中/取消选中等等。
对于用户来说,它必须看起来好像两个按钮都是相同的按钮,出现在层次结构中的多个位置(实际上Swing不允许这样做。)
我可以通过创建单个ButtonModel
并为两个按钮分配相同的模型来获得一半。这会同步其武装/已检查/选定状态等。
然而,按钮之间不共享的一个显着效果是焦点 - 单击一个按钮使该按钮成为焦点(由按钮内的矩形表示)并将其从另一个按钮中移除按钮。当 按钮确实有焦点时,我想将两个按钮渲染为好像它们一样聚焦。
有干净的方法吗?
理想情况下,我希望它独立于所选择的外观。
修改:我发现了共享ButtonModel
的另一个问题。当其中一个按钮失去焦点时,它会将模型的armed
和pressed
属性设置为false
。在处理mousePressed
之后发生这种情况,因此如果您在第一个按钮具有焦点时按下第二个按钮,则在您再次按下它之前它不会进入按下状态。
答案 0 :(得分:3)
通过对两个按钮使用相同的ButtonModel,您做了一个非常好的举动。
现在您的焦点问题。答案是否定的。没有L&F
不可知的方式。
您必须覆盖BasicButtonUI
(或您正在使用的ButtonUI
)并覆盖焦点绘制逻辑。
答案 1 :(得分:3)
这就是我的所作所为:
JButton
SharedFocusButton
SharedFocusButton
会覆盖hasFocus
,getModel
和paintBorder
。JButton.paintBorder(Graphics)
或ButtonUI.update(Component, Graphics)
正在运行时,暂时更改hasFocus
的行为,以便在组中的任何按钮具有焦点时返回true
。同时暂时更改getModel
的行为以返回代理ButtonModel
(有时会返回共享ButtonModel
)ButtonModel
的行为与默认的共享ButtonModel
相同,只是它拒绝将armed
或pressed
属性'值更改为false
,同时处理focusLost
事件。focusGained
和focusLost
,强制组中的所有按钮自行重绘(这不会自动发生,因为每个按钮都有自己的UI处理焦点事件。) 剩余问题:
应该修改焦点遍历,以便 Tab 键永远不会将焦点从一个按钮转移到同一组中的另一个按钮。
答案 2 :(得分:1)
我假设你已经整理了文字,听众等。
转到BasicButtonUI的paint方法,我们可以看到它在进行某些绘制之前实际检查按钮是否具有焦点。因此,除非您可以同时拥有两个聚焦组件,否则我能想到的唯一方法是使用其他按钮的UI进行绘制。
两个按钮都需要是FocusButton,并且需要相互调用setButton。除了其他方面,我没有费心去添加任何空检查。
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);
}
}
}
编辑:如果您的按钮尺寸不同,这种方法效果不佳,如果它们应该有不同的文字,显然根本不起作用。