概要

BevelBorderの射影のサイズを変更し、それをJButtonに設定します。

サンプルコード

class CustomBevelBorder extends BevelBorder {
  private final Insets i = new Insets(8, 8, 8, 8);
  protected CustomBevelBorder(int bevelType) {
    super(bevelType);
  }

  @Override public Insets getBorderInsets(Component c, Insets insets) {
    insets.set(i.top + 2, i.left + 2, i.bottom + 2, i.right + 2);
    return insets;
  }

  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    boolean isPressed = false;
    if (c instanceof AbstractButton) {
      ButtonModel m = ((AbstractButton) c).getModel();
      isPressed = m.isPressed();
    }
    if (bevelType == RAISED && !isPressed) {
      paintRaisedBevel(c, g, x, y, width, height);
    } else { // if (bevelType == LOWERED) {
      paintLoweredBevel(c, g, x, y, width, height);
    }
  }

  @Override protected void paintRaisedBevel(
      Component c, Graphics g, int x, int y, int width, int height)  {
    int w = width  - 1;
    int h = height - 1;

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.translate(x, y);

    g2.setPaint(getHighlightInnerColor(c));
    fillTopLeft(g2, w, h, i);

    g2.setPaint(getShadowInnerColor(c));
    g2.fill(makeBottomRightShape(w, h, i));

    g2.setPaint(getShadowOuterColor(c));
    drawRectLine(g2, w, h, i);

    g2.dispose();
  }

  @Override protected void paintLoweredBevel(
      Component c, Graphics g, int x, int y, int width, int height)  {
    int w = width  - 1;
    int h = height - 1;

    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.translate(x, y);

    g2.setPaint(getShadowInnerColor(c));
    fillTopLeft(g2, w, h, i);

    g2.setPaint(getHighlightInnerColor(c));
    g2.fill(makeBottomRightShape(w, h, i));

    g2.setPaint(getShadowOuterColor(c));
    drawRectLine(g2, w, h, i);

    g2.dispose();
  }

  private void fillTopLeft(Graphics2D g2, int w, int h, Insets i) {
    g2.fillRect(0, 0, w, i.top);
    g2.fillRect(0, 0, i.left, h);
  }

  private Shape makeBottomRightShape(int w, int h, Insets i) {
    Path2D p = new Path2D.Double();
    p.moveTo(w, 0);
    p.lineTo(w - i.right, i.top);
    p.lineTo(w - i.right, h - i.bottom);
    p.lineTo(i.left, h - i.bottom);
    p.lineTo(0, h);
    p.lineTo(w, h);
    p.closePath();
    return p;
  }

  private void drawRectLine(Graphics2D g2, int w, int h, Insets i) {
    g2.drawRect(0, 0, w, h);
    g2.drawRect(i.left, i.top, w - i.left - i.right, h - i.top - i.bottom);
    g2.drawLine(0, 0, i.left, i.top);
    g2.drawLine(w, 0, w - i.right, i.top);
    g2.drawLine(0, h, i.left, h - i.bottom);
    g2.drawLine(w, h, w - i.right, h - i.bottom);
  }
}
View in GitHub: Java, Kotlin

解説

  • Default BevelBorder
    • 射影の高さは2pxで固定
    • このサイズはBevelBorder#getBorderInsets(...)をオーバーライドして内余白を変更しても変化しない
  • Custom BevelBorder
    • BevelBorder#getBorderInsets(...)をオーバーライドして内余白を変更
    • BevelBorder#paintBorder(...)をオーバーライドしてJButtonの状態に応じてBevelBorder#paintRaisedBevel(...)BevelBorder#paintLoweredBevel(...)の描画を切り替えるよう設定
    • BevelBorder#paintRaisedBevel(...)をオーバーライドして内余白に応じたサイズの射影と境界線を描画
    • BevelBorder#paintLoweredBevel(...)をオーバーライドして内余白に応じたサイズの射影と境界線を描画

  • JButtonContentAreaの描画がLookAndFeelや初期値の関係で不正になる場合がある?
    • SwingUtilities.updateComponentTreeUI(...)を使用して回避

参考リンク

コメント