gpt4 book ai didi

java - 如何使用 Nimbus 外观更改表格单元格内的 JProgressbar 条形颜色

转载 作者:行者123 更新时间:2023-11-29 03:38:08 25 4
gpt4 key购买 nike

我的问题是我有一个表格,其中一列在表格单元格中有 ProgressBars,我想根据行号和列号动态更改 ProgressBar 的条形颜色,但是我无法实现它。 Nimbus 也有局限性。我必须基于每个组件覆盖 Nimbus UI 默认值。因此,如果我想动态更改单元格的条形颜色,如何在不更改单元格文本颜色的情况下实现它?

 public class ProgressRenderer extends JProgressBar implements TableCellRenderer {

private static final long serialVersionUID = 1L;

public ProgressRenderer(int min, int max) {
super(min, max);
this.setStringPainted(true);
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int row, int column) {
this.setValue((Integer) value);
UIDefaults defaults = new UIDefaults();
defaults.put("ProgressBar[Enabled].foregroundPainter", new MyPainter(Color.RED));
defaults.put("ProgressBar[Enabled+Finished].foregroundPainter", new MyPainter(Color.RED));

putClientProperty("Nimbus.Overrides.InheritDefaults", Boolean.TRUE);
putClientProperty("Nimbus.Overrides", defaults);
return this;
}

class MyPainter implements Painter<JProgressBar> {

private final Color color;

public MyPainter(Color c1) {
this.color = c1;
}
@Override
public void paint(Graphics2D gd, JProgressBar t, int width, int height) {
gd.setColor(color);
gd.fillRect(0, 0, width, height);
}
}
}

以上是我的代码片段,我使用了 TableCellRenderer。

最佳答案

类似的东西? ;)

Different JProgressBar on JTable cells

您遇到的问题是,为特定组件实例覆盖 Nimbus 的默认颜色是极其痛苦的(参见related question)。

大多数 Nimbus 画家都定义了大约 50 种不同的颜色,这些颜色源自一两个基本颜色(nimbusBlueGrey 和著名的 nimbusOrange)。最好的方法是在要更改的组件的 Nimbus.Override 属性中的 UIDefaults 中覆盖它们,但这不是他们所做的(我会喜欢在上面打开一个错误 ;),不认真!)。

我一直在尝试实现完全相同的事情,最终能够通过...(闭上眼睛)复制粘贴和破解 javax.swing.plaf.nimbus.ProgressBarPainter类到我自己的代码中!为什么?因为那个类是包私有(private)的,不能被覆盖(这样会更干净一些......)。尽管我讨厌这样做,但它奏效了......

这里是如何修改它(我不会发布整个代码,因为它太大而且没那么有趣):

  1. 首先在 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);
    }
  2. 将静态生成 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
}

您将在 NimbusDefaults 的源代码中找到如何初始化 ctx 字段。但是,请注意枚举 AbstractRegionPainter.PaintContext.CacheMode 在调整后的类中不可见,因此您将无法使用所有奇特的功能。幸运的是,AbstractRegionPainter.PaintContext 有一个不使用它的更简单的构造函数。(在我的例子中,我不需要所有不同的状态,所以我使用默认值,但可以随意添加任何其他参数来处理它们)。

最后, chalice ! ;)(我正在根据应该是百分比的值更改颜色: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;
}

现在,让我们稍微“清理”一下(尽可能多地称之为“清理”工作):

  • 删除使用 nimbusOrangeprivate Color colorXX 的分配,因为它们将通过调用 initColors() 生成。
  • 保留使用 nimbusBlueGrey 的分配,因为我们不会更改它们,并且不要将它们包含在 initColors() 中。剩下的 initColors() 生成 26 种颜色(17 到 28、30、33 到 44 和 50)。
  • 如果像我一样,您只有几种颜色来表示所有进度条,请预先生成您将使用的所有 ProgressBarPainter 并在 中分配正确的颜色getTableCellRendererComponent()
  • (或者在我的例子中创建三个 private static JProgressBar red, orange, green 并在 getTableCellRendererComponent() 中返回它们而不是 this )

关于java - 如何使用 Nimbus 外观更改表格单元格内的 JProgressbar 条形颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14468689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com