如何使用 SynthLookAndFeel 更改 "disabled icon" 样式?
How can I change the "disabled icon" style using SynthLookAndFeel?
我目前正在设计一个具有自定义 "yellow on black" 外观的 Swing 应用程序,SynthLookAndFeel 似乎是可行的方法。
我所有的按钮都包含一个 ImageIcon(无文本),例如:
当按钮被禁用时,我希望图标变成褪色的黄色:
但是,默认的禁用图标只是 "enabled" 图标的灰度版本,打破了黄色的感觉:
我在 this answer 中读到禁用图标是由 getDisabledIcon()
内部生成的,但我找不到从合成器的 XML 文件中控制它的地方。
我也读过 SynthLookAndFeel 的 SynthPainter class,但它似乎没有解决禁用图标的问题。
有没有一种方法可以使用 SynthLookAndFeel 来控制 "getDisabledIcon" 行为,还是我要求太多了?在后一种情况下,为了轻松定义按钮背景、形状等,最适合使用或扩展的外观和感觉是什么?
欢迎任何提示。
好的,我想我找到了一个干净的方法。
我在寻找使用 SynthLookAndFeel 的方法还是子类化另一个 L&F 之间犹豫不决...但没想到子类化 SynthLookAndFeel 本身:-)
我现在有一个 SynthLookAndFeel 的实现,它完全符合我的要求,这意味着 "disabled" 图标不是灰度图标,它是去饱和、暗淡的彩色版本:
这里是完整代码:
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);
}
}
结果比我想的简单多了。
我目前正在设计一个具有自定义 "yellow on black" 外观的 Swing 应用程序,SynthLookAndFeel 似乎是可行的方法。
我所有的按钮都包含一个 ImageIcon(无文本),例如:
当按钮被禁用时,我希望图标变成褪色的黄色:
但是,默认的禁用图标只是 "enabled" 图标的灰度版本,打破了黄色的感觉:
我在 this answer 中读到禁用图标是由 getDisabledIcon()
内部生成的,但我找不到从合成器的 XML 文件中控制它的地方。
我也读过 SynthLookAndFeel 的 SynthPainter class,但它似乎没有解决禁用图标的问题。
有没有一种方法可以使用 SynthLookAndFeel 来控制 "getDisabledIcon" 行为,还是我要求太多了?在后一种情况下,为了轻松定义按钮背景、形状等,最适合使用或扩展的外观和感觉是什么?
欢迎任何提示。
好的,我想我找到了一个干净的方法。
我在寻找使用 SynthLookAndFeel 的方法还是子类化另一个 L&F 之间犹豫不决...但没想到子类化 SynthLookAndFeel 本身:-)
我现在有一个 SynthLookAndFeel 的实现,它完全符合我的要求,这意味着 "disabled" 图标不是灰度图标,它是去饱和、暗淡的彩色版本:
这里是完整代码:
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);
}
}
结果比我想的简单多了。