Summary

JSeparatorの描画にRadialGradientPaintを使用してその両端がフェードアウトするよう描画します。

Source Code Examples

class GradientSeparatorUI extends BasicSeparatorUI {
  private Color backgroundColor;
  private Color shadowColor;
  private Color highlightColor;

  public static ComponentUI createUI(JComponent c) {
    return new GradientSeparatorUI();
  }

  private void updateColors(Component c) {
    Color bgc = c.getBackground();
    Color c1 = UIManager.getColor("Panel.background");
    backgroundColor = c1 instanceof ColorUIResource ? c1 : bgc;
    Color c2 = UIManager.getColor("Separator.shadow");
    shadowColor = c2 instanceof ColorUIResource ? c2 : bgc.darker();
    Color c3 = UIManager.getColor("Separator.highlight");
    highlightColor = c3 instanceof ColorUIResource ? c3 : bgc.brighter();
  }

  @Override public void installUI(JComponent c) {
    super.installUI(c);
    updateColors(c);
  }

  @Override public void paint(Graphics g, JComponent c) {
    if (c instanceof JSeparator) {
      Graphics2D g2 = (Graphics2D) g.create();
      Rectangle r = SwingUtilities.calculateInnerArea(c, null);
      float centerX = (float) r.getCenterX();
      float centerY = (float) r.getCenterY();
      Point2D center = new Point2D.Float(centerX, centerY);
      float radius = Math.max(r.width, r.height);
      float[] dist = {.1f, .6f};
      Color[] colors1 = {shadowColor, backgroundColor};
      // = {shadow, shadow, background, background}, {0f, .1f, .6f, 1f}
      Paint p1 = new RadialGradientPaint(center, radius, dist, colors1);
      Color[] colors2 = {highlightColor, backgroundColor};
      Paint p2 = new RadialGradientPaint(center, radius, dist, colors2);
      if (((JSeparator) c).getOrientation() == SwingConstants.HORIZONTAL) {
        g2.setPaint(p1);
        g2.fillRect(0, 0, r.width, 1);
        g2.setPaint(p2);
        g2.fillRect(0, 1, r.width, 1);
      } else {
        g2.setPaint(p1);
        g2.fillRect(0, 0, 1, r.height);
        g2.setPaint(p2);
        g2.fillRect(1, 0, 1, r.height);
      }
      g2.dispose();
    }
  }
}
View in GitHub: Java, Kotlin

Description

  • Separatorのグラデーションと同様にBasicSeparatorUI#paint(...)をオーバーライドしてJSeparatorを描画
    • グラデーションにGradientPaintではなくRadialGradientPaintを使用して両端がフェードアウトするよう中心、半径、グラデーションに沿った色の分布、グラデーションで使用する色の配列を設定
  • グラデーションで使用する色は、UIManager.getColor(...)からPanel.backgroundSeparator.shadowSeparator.highlightを取得して設定する

Reference

Comment