概要

JTextFieldの角を丸めて表示するようBorderを設定しています。

サンプルコード

//Unleash Your Creativity with Swing and the Java 2D API!
//http://web.archive.org/web/20091205092230/http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html
JTextField textField01 = new JTextField(20) {
  @Override protected void paintComponent(Graphics g) {
    if (!isOpaque()) {
      int w = getWidth() - 1;
      int h = getHeight() - 1;
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setPaint(UIManager.getColor("TextField.background"));
      g2.fillRoundRect(0, 0, w, h, h, h);
      g2.setPaint(Color.GRAY);
      g2.drawRoundRect(0, 0, w, h, h, h);
      g2.dispose();
    }
    super.paintComponent(g);
  }
  @Override public void updateUI() {
    super.updateUI();
    setOpaque(false);
    setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));
  }
};
view all

解説

    • RoundedCornerBorderを設定
    • 角を親コンポーネントの背景色で上書きしているので、背景が画像などの場合はその上に角が描画されてしまう
    • JTextFieldは透明にし、RoundedCornerBorderから取得した図形で背景色を描画するように修正
JTextField textField02 = new JTextField(20) {
  @Override protected void paintComponent(Graphics g) {
    if (!isOpaque() && getBorder() instanceof RoundedCornerBorder) {
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setPaint(getBackground());
      g2.fill(((RoundedCornerBorder) getBorder()).getBorderShape(
          0, 0, getWidth() - 1, getHeight() - 1));
      g2.dispose();
    }
    super.paintComponent(g);
  }
  @Override public void updateUI() {
    super.updateUI();
    setOpaque(false);
    setBorder(new RoundedCornerBorder());
  }
};

class RoundedCornerBorder extends AbstractBorder {
  private static final Color ALPHA_ZERO = new Color(0x0, true);
  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    Shape border = getBorderShape(x, y, width - 1, height - 1);
    g2.setPaint(ALPHA_ZERO);
    Area corner = new Area(new Rectangle2D.Double(x, y, width, height));
    corner.subtract(new Area(border));
    g2.fill(corner);
    g2.setPaint(Color.GRAY);
    g2.draw(border);
    g2.dispose();
  }
  public Shape getBorderShape(int x, int y, int w, int h) {
    int r = h; //h / 2;
    return new RoundRectangle2D.Double(x, y, w, h, r, r);
  }
  @Override public Insets getBorderInsets(Component c) {
    return new Insets(4, 8, 4, 8);
  }
  @Override public Insets getBorderInsets(Component c, Insets insets) {
    insets.set(4, 8, 4, 8);
    return insets;
  }
}

参考リンク

コメント

  • TextUI#paintSafely(...)をオーバーライドして、JTextField内を上書きする方法はやめて、Area#subtractで切り抜いた図形を親の背景色で描画する方法に変更。 -- aterai