概要

JLayerを使ってJProgressBarの色相を緑から赤に変更します。

サンプルコード

class BlockedColorLayerUI extends LayerUI<JProgressBar> {
  public boolean isPreventing;
  private transient BufferedImage bi;
  private int prevw = -1;
  private int prevh = -1;

  @Override public void paint(Graphics g, JComponent c) {
    if (isPreventing && c instanceof JLayer) {
      JLayer jlayer = (JLayer) c;
      JProgressBar progress = (JProgressBar) jlayer.getView();
      int w = progress.getSize().width;
      int h = progress.getSize().height;

      if (bi == null || w != prevw || h != prevh) {
        bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
      }
      prevw = w;
      prevh = h;

      Graphics2D g2 = bi.createGraphics();
      super.paint(g2, c);
      g2.dispose();

      Image image = c.createImage(new FilteredImageSource(
          bi.getSource(), new RedGreenChannelSwapFilter()));
      g.drawImage(image, 0, 0, null);
    } else {
      super.paint(g, c);
    }
  }
}

class RedGreenChannelSwapFilter extends RGBImageFilter {
  @Override public int filterRGB(int x, int y, int argb) {
    int r = (int) ((argb >> 16) & 0xFF);
    int g = (int) ((argb >> 8) & 0xFF);
    int b = (int) (argb & 0xFF);
    return (argb & 0xFF_00_00_00) | (g << 16) | (r << 8) | (b);
  }
}
View in GitHub: Java, Kotlin

解説

  • setStringPainted(true): 上
    • デフォルトのJProgressBarJProgressBar#setStringPainted(true)を設定
  • setStringPainted(true): 下
    • JProgressBar#setStringPainted(true)を設定
    • チェックボックスが選択された場合JProgressBar#setForeground(Color)で色を変更
  • setStringPainted(false): 上
    • デフォルトのJProgressBar
  • setStringPainted(false): 下
    • チェックボックスが選択された場合JLayerを使って色を変更
      • Windows 7での中断状態風に緑を赤に入れ替えるためRGBImageFilter#filterRGB(...)をオーバーライド

参考リンク

コメント