首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以在运行时更改组件样式?

是否可以在运行时更改组件样式?
EN

Stack Overflow用户
提问于 2013-07-18 19:56:40
回答 1查看 328关注 0票数 0

我使用swing + nimbus来样式化我的组件。我想在运行时使用"Nimbus.Overrides“更改组件的样式。

代码语言:javascript
复制
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()方法,它是有效的。我得到一个红色的背景。当我第二次使用这个的时候,什么也没有发生。看起来,重写只评估一次。

我想要的是引入一种新的密码字段状态,并使其具有不同的样式。有没有可能这样做呢?

诚挚的问候,

Yggdrasil

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-07-18 21:21:30

是的,这是可能的,并且Nimbus实际上监听"Nimbus.Overrides“的变化-只是:如果它们是!instanceof UIResource,它不会卸载一些属性,至少对于背景,前景,字体(也可能是其他的)

在您的上下文中,您最初确实安装了一个不是it的RED资源,有效地告诉laf不要再接触它-并且它遵守:-)

我能让它工作的唯一方法是在设置新的覆盖之前将背景置为空,就像下面这样:

代码语言:javascript
复制
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最小的不受欢迎的孩子一样;-)的方法是

  • implement a custom state
  • 在需要时使用该状态的

属性注册附加状态

所有这些配置都必须在安装LAF之后和实例化第一个JPasswordField之前完成,如果在运行时切换LAF,很可能(没有测试)会出现问题。

代码语言:javascript
复制
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();
    }
};
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17722812

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档