通过自定义 buttonmodel 并同时重写 `ispressed()` 和 `isarmed()` 方法,可使 jbutton 在任意时刻(包括鼠标移出时)稳定显示按下态,适用于 windows classic 等原生 l&f。
在 Swing 中,JButton 的视觉按下效果并非仅由 isPressed() 决定——它还高度依赖 isArmed() 状态。isArmed() 表示按钮“已准备就绪、处于待触发状态”,在 Windows Classic(及多数系统级 Look & Feel)中,只有当 isArmed() == true 时,按钮才会渲染为深色凹陷的“按下外观”;而仅设置 isPressed() 为 true,往往只在鼠标悬停+未释放时短暂生效,一旦鼠标移出即失效。
因此,要实现全局、持久、与鼠标位置无关的按下态视觉效果,必须同步覆盖两个方法:
class PressedStateButtonModel extends DefaultButtonModel {
private boolean forcedPressed;
public PressedStateButtonModel(boolean initiallyPressed) {
this.forcedPressed = initiallyPressed;
}
public void setForcedPressed(boolean pressed) {
this.forcedPressed = pressed;
// 触发 UI 重绘
fireStateChanged();
}
@Override
public boolean isPressed() {
return super.isPressed() || forcedPressed;
}
@Override
public boolean isArmed() {
return super.isArmed() || forcedPressed;
}
}
使用方式(假设 myButton 是你继承自 JButton 的自定义按钮类):