类似的东西?;)
您遇到的问题是,为特定组件实例覆盖 Nimbus 的默认颜色非常痛苦(请参阅相关问题)。
大多数 Nimbus 画家定义了大约 50 种不同的颜色,这些颜色源自一两个基本颜色(thenimbusBlueGrey
和 Famous nimbusOrange
)。最好的方法是在要更改的组件的UIDefaults
found inNimbus.Override
属性中覆盖它们,但这不是他们所做的(我想打开一个错误;),不认真!)。
我一直在努力实现完全相同的目标,最终能够通过......(闭上眼睛)复制粘贴并将javax.swing.plaf.nimbus.ProgressBarPainter
类破解到我自己的代码中!为什么?因为该类是包私有的,不能被覆盖(这会更干净一些......)。尽管我讨厌这样做,但它确实有效......
这是修改它的方法(我不会发布整个代码,因为它太大而且没那么有趣):
ProgressBarPainter()
首先在构造函数之后添加以下方法。(它们基本上是您可以按照该decodeColor()
方法找到的内容的复制粘贴,AbstractRegionPainter
然后NimbusLookAndFeel
再到NimbusDefaults.getDerivedColor()
最后DerivedColor.rederiveColor()
):
private float clamp(float v) {
if (v < 0.0f)
return 0.0f;
if (v > 1.0f)
return 1.0f;
return v;
}
private int clamp(int v) {
if (v < 0)
return 0;
if (v > 255)
return 255;
return v;
}
// Got from javax.swing.plaf.nimbus.DerivedColor.rederiveColor()
private Color decodeColor(Color src, float hOffset, float sOffset, float bOffset, int aOffset) {
float[] tmp = Color.RGBtoHSB(src.getRed(), src.getGreen(), src.getBlue(), null);
tmp[0] = clamp(tmp[0] + hOffset);
tmp[1] = clamp(tmp[1] + sOffset);
tmp[2] = clamp(tmp[2] + bOffset);
int alpha = clamp(src.getAlpha() + aOffset);
return new Color((Color.HSBtoRGB(tmp[0], tmp[1], tmp[2]) & 0xFFFFFF) | (alpha << 24), true);
}
将静态生成 50 种颜色的代码复制粘贴到您将用于动态生成它们的方法中,从您想要的颜色:
从 :
private Color color1 = decodeColor("nimbusBlueGrey", 0.0f, -0.04845735f, -0.17647058f, 0);
...
private Color color50 = decodeColor("nimbusOrange", 0.0014062226f, -0.77816474f, 0.12941176f, 0);
至:
private void initColors(Color foreground) {
color1 = decodeColor("nimbusBlueGrey", 0.0f, -0.04845735f, -0.17647058f, 0);
// ...
color50 = decodeColor(foreground, 0.0014062226f, -0.77816474f, 0.12941176f, 0);
}
请注意,我们将我们想要的颜色作为参数传递,并将其用作 的替代品nimbusOrange
,这似乎是进度条的主要颜色。我们尝试坚持 Nimbus 派生颜色的方式。
并更改ProgressBarPainter()
构造函数以包含主要颜色并生成它们:
public ProgressBarPainter(int state, Color foreground) {
super();
this.state = state;
this.ctx = new AbstractRegionPainter.PaintContext(new Insets(5, 5, 5, 5), new Dimension(29, 19), false);
initColors(foreground); // Generates appropriate colors
}
您将ctx
在NimbusDefaults
. 但是,请注意枚举AbstractRegionPainter.PaintContext.CacheMode
在调整后的类中不可见,因此您将无法使用所有花哨的功能。幸运的是,有一个更简单的构造函数AbstractRegionPainter.PaintContext
不使用它。(就我而言,我不需要所有不同的状态,所以我使用默认值,但可以随意添加任何其他参数来处理它们)。
最后,Graal!;) (我正在根据应该是百分比的值更改颜色:green
如果超过 75%,orange
如果超过 50%,red
否则)。
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
int v = ((Integer)value).intValue();
Color c;
if (val >= 75)
c = Color.GREEN;
else if (val >= 50)
c = Color.ORANGE;
else
c = Color.RED;
setValue(v);
UIDefaults defaults = new UIDefaults();
ProgressBarPainter painter = new ProgressBarPainter(ProgressBarPainter.FOREGROUND_ENABLED, c);
defaults.put("ProgressBar[Enabled].foregroundPainter", painter);
putClientProperty("Nimbus.Overrides", defaults);
return this;
}
现在,让我们稍微“清理”一下(我们可以称之为“清理”工作):
- 删除
private Color colorXX
那些使用的分配nimbusOrange
,因为它们将由调用生成initColors()
。
- 保留这些使用的分配
nimbusBlueGrey
,因为我们不会更改它们,并且不要将它们包含在initColors()
. 这样就可以initColors()
生成 26 种颜色(17 到 28、30、33 到 44 和 50)。
- 如果像我一样,您只有几种颜色可以代表所有进度条,请预先生成
ProgressBarPainter
您将使用的所有 s 并在getTableCellRendererComponent()
- (或者在我的情况下,使用适当的覆盖颜色画家创建三个
private static JProgressBar red, orange, green
并返回它们而不是this
in getTableCellRendererComponent()
)