通过自定义 buttonmodel 并同时重写 `ispressed()` 和 `isarmed()` 方法,可使 jbutton 在任意时刻(无论鼠标位置或是否点击)稳定呈现按下视觉状态,适用于 windows classic 等 l&f 下的精确 ui 控制。
在 Swing 中,JButton 的“按下”外观(pressed appearance)并非仅由 isPressed() 决定——它还高度依赖 isArmed() 方法。isArmed() 表示按钮是否处于“已预激活”状态(即准备响应点击),而多数 Look & Feel(尤其是 Windows Classic、Windows、Metal 等)会将 armed && pressed 作为渲染“深陷式按下效果”的关键条件。若只重写 isPressed(),按钮仅在鼠标悬停(自动触发 arm())时显示按下态;一旦鼠标移出,isArmed() 返回 false,视觉状态立即恢复常态。
✅ 正确做法是:同步控制 isPressed() 和 isArmed(),确保二者在业务逻辑需要时均返回 true:
class ForcedPressedButtonModel extends DefaultButtonModel {
private boolean forcedPressed;
public void setForcedPressed(boolean forced) {
boolean old = this.forcedPressed;
this.forcedPressed = forced;
// 通知 UI 状态变更,触发重绘
fireStateChanged();
}
@Override
public boolean isPressed() {
return super.isPressed() || forcedPressed;
}
@Override
public boolean isArmed() {
return super.isArmed() || forcedPressed;
}
}
使用示例: