2013-07-18 50 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

相關問題