概要

Iconインタフェースから固定サイズのアイコンを作成します。

サンプルコード

class DragHereIcon implements Icon {
  private static final int ICON_WIDTH = 100;
  private static final int ICON_HEIGHT = 100;
  private static final float BORDER_SIZE = 8f;
  private static final float SLIT_WIDTH = 8f;
  private static final int ARC_SIZE = 16;
  private static final int SLIT_NUM = 3;
  private static final Shape BORDER = new RoundRectangle2D.Double(
      BORDER_SIZE,
      BORDER_SIZE,
      ICON_WIDTH - 2 * BORDER_SIZE - 1,
      ICON_HEIGHT - 2 * BORDER_SIZE - 1,
      ARC_SIZE, ARC_SIZE);
  private static final Font FONT = new Font(
      Font.MONOSPACED, Font.BOLD, ICON_WIDTH);
  private static final Color LINE_COLOR = Color.GRAY;

  @Override public void paintIcon(
        Component c, Graphics g, int x, int y) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.translate(x, y);
    g2.setStroke(new BasicStroke(BORDER_SIZE));
    g2.setPaint(LINE_COLOR);
    g2.draw(BORDER);
    g2.setStroke(new BasicStroke(SLIT_WIDTH));
    g2.setPaint(UIManager.getColor("Panel.background"));

    int n = SLIT_NUM + 1;
    int v = ICON_WIDTH / n;
    int m = n * v;
    for (int i = 1; i < n; i++) {
      int a = i * v;
      g2.drawLine(a, 0, a, m);
      g2.drawLine(0, a, m, a);
    }
    FontRenderContext frc = g2.getFontRenderContext();
    Shape arrow = new TextLayout("⇩", FONT, frc).getOutline(null);
    g2.setPaint(LINE_COLOR);
    Rectangle2D b = arrow.getBounds2D();
    double cx = ICON_WIDTH / 2d - b.getCenterX();
    double cy = ICON_HEIGHT / 2d - b.getCenterY();
    AffineTransform toCenterAt = AffineTransform.getTranslateInstance(cx, cy);
    g2.fill(toCenterAt.createTransformedShape(arrow));
    g2.dispose();
  }

  @Override public int getIconWidth()  {
    return ICON_SIZE;
  }

  @Override public int getIconHeight() {
    return ICON_SIZE;
  }
}
View in GitHub: Java, Kotlin

解説

上記のサンプルでは、以下のようにIconインタフェースを実装してアイコンを作成しています。フチもアイコンの内部に描画していますがBasicStrokeの破線ではなく背景色と同じ色の直線でパターンを表現しています。

  • Icon#paintIcon(Component c, Graphics g, int x, int y)メソッドをオーバーライドして実装
    • 原点を移動
    • ラウンド矩形でフチを描画
    • 直線で格子状のスリットを上書き
    • 矢印のアウトラインをフォントから取得して中心に描画
    • 原点を戻す
      • 直接g.translate(x, y)で原点を変更した場合g.translate(-x, -y)で元に戻す必要がある
      • またはGraphics2D g2 = (Graphics2D) g.create()で別のGraphicsを生成して原点を移動した場合は最後にg2.dispose()メソッドでGraphics2Dを破棄する
  • Icon#getIconWidth()Icon#getIconHeight()メソッドをオーバーライドしてアイコンのサイズを指定

参考リンク

コメント