【问题标题】:How can I change the "disabled icon" style using SynthLookAndFeel?如何使用 SynthLookAndFeel 更改“禁用图标”样式?
【发布时间】:2020-09-04 20:58:27
【问题描述】:

我目前正在设计一个具有自定义“黑底黄字”外观的 Swing 应用程序,看来 SynthLookAndFeel 是要走的路。

我所有的按钮都包含一个 ImageIcon(无文本),例如:

当按钮被禁用时,我希望图标变成淡黄色:

但是,默认禁用的图标只是“启用”图标的灰度版本,这打破了黄色的感觉:

我在this answer 中读到,禁用的图标是由getDisabledIcon() 在内部生成的,但我找不到从合成器的 XML 文件中控制它的地方。

我还阅读了 SynthLookAndFeel 的 SynthPainter class,但它似乎没有解决禁用图标的问题。

有没有办法使用 SynthLookAndFeel 控制“getDisabledIcon”行为,还是我要求太多?在后一种情况下,最适合使用或扩展以轻松定义按钮背景、形状等的外观和感觉是什么?

欢迎任何提示。

【问题讨论】:

  • setDisabledIcon 呢?
  • 好吧,getDisabledIcon 的名字很糟糕,因为它不是一个字段获取器,我想它应该命名为createDisabledIcon,因为它需要一个组件和一个图标作为参数并处理图标以返回一个灰度版本其中。因此,没有setDisabledIcon 方法...

标签: java swing look-and-feel synth


【解决方案1】:

好的,我想我找到了一个干净的方法。

我在寻找使用 SynthLookAndFeel 的方法还是继承另一个 L&F 之间犹豫不决...但没有想到继承 SynthLookAndFeel 本身:-)

我现在有了一个 SynthLookAndFeel 的实现,它完全符合我的要求,这意味着“禁用”图标不是灰度图标,它是一个不饱和、暗淡的彩色版本:

这里是完整的代码:

import javax.swing.*;
import javax.swing.plaf.synth.SynthLookAndFeel;
import java.awt.*;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;

public class MySynthLookAndFeel extends SynthLookAndFeel {
    @Override
    public Icon getDisabledIcon(JComponent component, Icon icon) {
        if (icon instanceof ImageIcon) {
            return new ImageIcon(createDisabledImage(((ImageIcon)icon).getImage()));
        }
        return null;
    }

    private static Image createDisabledImage(Image i) {
        ImageProducer prod = new FilteredImageSource(i.getSource(), new RGBImageFilter() {
            public int filterRGB(int x, int y, int rgb) {
                // extract alpha mask
                int alphamask = rgb & 0xFF000000;

                // convert to HSB
                float[] hsb = Color.RGBtoHSB((rgb >> 16) & 0xff, (rgb >> 8) & 0xff, rgb & 0xff, null);
                // desaturate (half saturation)
                hsb[1] *= 0.5;
                // dim (half brightness)
                hsb[2] *= 0.5;
                // convert back to RGB
                int rgbval = Color.HSBtoRGB(hsb[0], hsb[1], hsb[2]);

                // reapply alpha
                rgbval = rgbval & 0x00FFFFFF | alphamask;
                return rgbval;
            }
        });
        return Toolkit.getDefaultToolkit().createImage(prod);
    }
}

最终,比我想象的要简单得多。

【讨论】:

    猜你喜欢
    • 2018-02-28
    • 2014-01-01
    • 1970-01-01
    • 2019-03-06
    • 2011-08-21
    • 2013-06-25
    • 2013-04-26
    • 2014-07-02
    • 1970-01-01
    相关资源
    最近更新 更多