1

私の問題は、列の1つがテーブルセル内にProgressBarsを持っているテーブルを持っていることです。行と列の番号に基づいて、ProgressBarのバーの色を動的に変更したいのですが、達成できません。また、ニンバスの制限もあります。コンポーネントごとにNimbusUIのデフォルトをオーバーライドする必要があります。では、セルのバーの色を動的に変更したい場合、セルのテキストの色を変更せずにそれを実現するにはどうすればよいですか?

 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を使用するコードスニペットです。

4

2 に答える 2

2

別の方法として、私が最終的に行ったことは、進行状況バーを拡張JPanelして、必要な色でペイントすることでした。

色付きのカスタム描画プログレス バー

public class ProgressBarCellRenderer extends JPanel implements TableCellRenderer {

    int val = 0;

    private static Paint generatePaint(Color c, int height) {
        return new LinearGradientPaint(0.0f, 0.0f, 0.0f, (float)height, new float[]{0.0f, 0.5f, 1.0f}, new Color[]{c.darker(), c.brighter(), c.darker()}, CycleMethod.REFLECT);
    }

    private static Paint greenPaint = generatePaint(Color.GREEN);
    private static Paint orangePaint = generatePaint(Color.ORANGE);
    private static Paint redPaint = generatePaint(Color.RED);

    @Override
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g;
        int x = 1;
        int y = 1;
        int w = getWidth()-2;
        int h = getHeight()-2;
        g2d.setColor(Color.LIGHT_GRAY);
        g2d.fillRect(x, y, w, h);
        Paint backPaint;
        if (val >= 75)
            backPaint = greenPaint;
        else if (val >= 50)
            backPaint = orangePaint;
        else
            backPaint = redPaint;
        g2d.setPaint(backPaint);
        int wd = (int)Math.round(w * val / 100.0);
        g2d.fillRect(x, y, wd, h);
        g2d.draw3DRect(x, y, wd, h, true);
        // Draw some text here if you want
    }
}

結果は私にとっては十分に良さそうで、「Nimbus hack」よりもはるかにクリーン (かつ効率的) だと思います!

于 2013-06-28T07:37:09.480 に答える
2

そんな感じ?;)

JTable セルの異なる JProgressBar

問題は、特定のコンポーネント インスタンスの Nimbus のデフォルト カラーをオーバーライドするのが非常に面倒なことです (関連する質問を参照してください)。

nimbusBlueGreyほとんどの Nimbus ペインターは、1 つまたは 2 つの基本的な色 (と 有名な)から派生した約 50 の異なる色を定義していnimbusOrangeます。最善の方法は、変更したいコンポーネントのUIDefaultsfound inプロパティでそれらをオーバーライドすることでした。Nimbus.Override

私はまったく同じことを達成しようとしてきましたが、最終的に...(目を閉じて)javax.swing.plaf.nimbus.ProgressBarPainterクラスを自分のコードにコピーアンドペーストしてハッキングすることができました!なんで?そのクラスはパッケージに対してプライベートであり、オーバーライドできないためです(これは少しきれいだったでしょう...)。私がそれをするのが嫌いな限り、それはうまくいきました...

これを変更する方法は次のとおりです(コードが大きすぎてそれほど面白くないため、コード全体は投稿しません)。

  1. ProgressBarPainter()コンストラクターの後に次のメソッドを追加することから始めます。(それらは基本的に、 thenと finallyまでのdecodeColor()メソッドに従って見つけることができるものをコピーして貼り付けたものです):AbstractRegionPainterNimbusLookAndFeelNimbusDefaults.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
}

ctxのソースでフィールドを初期化する方法を見つけることができますNimbusDefaults。ただし、列挙AbstractRegionPainter.PaintContext.CacheMode型は微調整されたクラスからは見えないため、すべての派手な機能を使用できないことに注意してください。AbstractRegionPainter.PaintContext幸いなことに、それを使用しない単純なコンストラクターがあります。(私の場合、さまざまな状態のすべてが必要なわけではないので、デフォルト値を使用しましたが、それらに対処するために他のパラメーターを自由に追加してください)。

そして最後はグラール!;) (パーセンテージである必要がある値に応じて色を変更しています: green75% を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を使用する の割り当てを削除します。nimbusOrangeinitColors()
  • を使用するこれらの割り当てnimbusBlueGreyは変更しないためそのままにして、 に含めないでくださいinitColors()。これにより、initColors()生成される 26 色 (17 ~ 28、30、33 ~ 44、および 50) が残ります。
  • 私のように、すべてのプログレス バーを表す色が数色しかない場合は、使用するすべてProgressBarPainterの を事前に生成し、正しい色を割り当てます。getTableCellRendererComponent()
  • (または私の場合private static JProgressBar red, orange, green、適切なオーバーライドされたカラーペインターで3つ作成し、代わりにそれらを返しthisますgetTableCellRendererComponent()
于 2013-06-28T07:27:38.820 に答える