2013-07-18 54 views
0

我使用swing + nimbus来设计我的组件。我想用“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); 
} 

我第一次设置的覆盖,让与它的工作原理SetExceptionState()方法说。我得到一个红色的背景。我第二次使用这个没有任何反应。看来,覆盖只被评估一次。

我想要的是引入一个新的passwordfield状态,并且它的风格有所不同。有没有可能这样做?

最好的问候,

Yggdrasil的

+0

无关:请学习java命名约定并坚持使用它们。 – kleopatra

+0

关于命名约定,在C#和java中同时进行编程并不容易... – Yggdrasil

+0

明白 - 但是如果你想在两个世界都能成功的话,你可能会考虑尝试一下:-) – kleopatra

回答

6

是的,这是可能的,实际上雨云监听到“Nimbus.Overrides”的变化 - 只是:如果他们是!instanceof UIResource这情况下,它不会卸载某些属性对于背景,前景,字体至少(可能是其他人)

在你的情况下,你最初安装了RED的非uiresource,有效地告诉laf不要再触摸它 - 它遵守:-)

,我可以让它工作,唯一的办法是设置新的覆盖,像以前一样为null背景:

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); 
} 

更新

其实,上面并没有回答真正问题:

介绍passwordfield和风格的一个新的状态也不同

雨云的确确实允许用合成器的那失宠最小的孩子添加自定义状态(虽然结果有些unpredicable,经常;-)要走的路是

  • 实现自定义的国家
  • 与UI-默认
  • 附上该状态的属性根据需要

所有这些配置具有寄存器产生额外状态之后安装了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(); 
    } 
}; 
+0

不确定!instanceof UIResource'有趣的可能是我的问题,不知道如果XxxRenderer杀死画家或背景,编辑无关紧要的noncompound JComponets作为渲染器组件,编辑第二,但可以学习本月项目如果是真的(不包括JButton) – mKorbel

+0

Thx它工作得很好。 – Yggdrasil

+0

:-) hehehe ....................... aaaach +1 – mKorbel

相关问题