はい、それは可能であり、Nimbus は実際に "Nimbus.Overrides" の変更をリッスンします - ただ: 一部のプロパティがアンインストールされていない場合、それらはアンインストールされません。これは!instanceof UIResource
、少なくとも背景、前景、フォントの場合です (他の場合もあるかもしれません)。
あなたのコンテキストでは、最初にREDのnot-uiresourceをインストールし、lafに二度と触れないように効果的に伝えました-そしてそれは準拠しています:-)
私がそれを機能させる唯一の方法は、次のように、新しいオーバーライドを設定する前に背景を無効にすることでした:
private void setExceptionState(JComponent password) {
password.setBackground(null);
UIDefaults overrides = new UIDefaults();
overrides.put("PasswordField.background", Color.RED);
password.putClientProperty("Nimbus.Overrides", overrides);
}
private void resetExceptionState(JComponent password) {
password.setBackground(null);
UIDefaults overrides = new UIDefaults();
overrides.put("PasswordField.background", Color.WHITE);
password.putClientProperty("Nimbus.Overrides", overrides);
}
アップデート
実際、上記は本当の質問に答えていません:
パスワードフィールドの新しい状態を導入し、スタイルを変えます
実際、Nimbus ではカスタム状態を追加できます (ただし、Synth の愛されていない最年少の子と同様に、結果はいくぶん予測できません ;-) 方法は次のとおりです。
- カスタム状態を実装する
- 追加の状態を ui-defaults に登録します
- 必要に応じてその状態のプロパティをアタッチします
LAF がインストールされた後、最初の JPasswordField がインスタンス化される前に、このすべての構成を行う必要があります。LAF が実行時に切り替えられると、おそらく (テストしていませんが) 問題が発生します。
protected void installCustomPasswordFieldState() {
// implement a custom state
State<JPasswordField> state = new State<JPasswordField>("Invalid") {
@Override
protected boolean isInState(JPasswordField c) {
Object invalid = c.getClientProperty("Invalid");
return Boolean.TRUE.equals(invalid);
}
};
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
// register available states
// note: couldn't find a way to grab the already available states
// so this is guesswork
defaults.put("PasswordField.States", "Enabled, Focused, Invalid");
// install the custom state
defaults.put("PasswordField.Invalid", state);
// install the properties for the custom state
// note: background has no effect
defaults.put("PasswordField[Invalid].background",
Color.RED);
javax.swing.Painter<JComponent> p = new javax.swing.Painter<JComponent>() {
@Override
public void paint(Graphics2D g, JComponent object, int width, int height) {
g.setColor(Color.RED);
// this is crude - overpainting the complete area, do better!
g.fillRect(0, 0, width, height);
}
};
// using a painter has an effect
defaults.put("PasswordField[Invalid].backgroundPainter", p);
}
// example usage, toggling
// a new property (for simplicity implemented as clientProperty
// to toggle the invalid state
Action reset = new AbstractAction("reset") {
@Override
public void actionPerformed(ActionEvent e) {
boolean isInvalid = Boolean.TRUE.equals(field.getClientProperty("Invalid"));
if (isInvalid) {
field.putClientProperty("Invalid", null);
} else {
field.putClientProperty("Invalid", Boolean.TRUE);
}
field.repaint();
}
};