Reputation: 1427
I use swing + nimbus to style my component. I want to change the style of a component at runtime with "Nimbus.Overrides".
private void SetExceptionState() {
//password.setBackground(new Color(200,0,0,120));
UIDefaults overrides = new UIDefaults();
overrides.put("PasswordField.background", Color.red);
password.putClientProperty("Nimbus.Overrides", overrides);
password.revalidate();
password.updateUI();
}
private void ResetExceptionState() {
//password.setBackground(Color.white);
UIDefaults overrides = new UIDefaults();
overrides.put("PasswordField.background", Color.white);
password.putClientProperty("Nimbus.Overrides", overrides);
}
The first time I set the overrides, lets say with SetExceptionState() method it works. I get a red background. The second time I use this nothing happens. It seems, that the overrides are evaluated only once.
What I want is to introduce a new state ofthe passwordfield and style it different. Is there any possibility to do so?
Best regards,
Yggdrasil
Upvotes: 0
Views: 372
Reputation: 51524
Yes, it is possible and Nimbus actually listens to changes of the "Nimbus.Overrides" - just: it does not uninstall some properties if they are !instanceof UIResource
That's the case for background, foreground, font at least (might be others as well)
In your context, you did install a not-uiresource of RED initially, effectively telling the laf to not touch it again - and it complies :-)
The only way I could make it work, was to null the background before setting the new overrides, like in:
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);
}
Update
Actually, the above doesn't answer the real question:
introduce a new state of the passwordfield and style it different
Nimbus indeed does allow to add custom states (though the outcome is somewhat unpredicable, as often with that unloved youngest child of Synth ;-) The way to go is
All this configuration has to be done after the LAF is installed and before the first JPasswordField is instantiated, most probably (didn't test) posing problems if the LAF is switched at runtime.
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();
}
};
Upvotes: 6