• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextFieldの角を丸める
#navi(../)
#tags(JTextField, Border, Shape)
RIGHT:Posted by &author(aterai); at 2010-10-04
*JTextFieldの角を丸める [#f7c187e5]
角丸の``JTextField``を作成します。
//コードは主に[http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html Unleash Your Creativity with Swing and the Java 2D API!]から引用しています。
---
category: swing
folder: RoundedTextField
title: JTextFieldの角を丸める
tags: [JTextField, Border, Shape]
author: aterai
pubdate: 2010-10-04T21:07:50+09:00
description: JTextFieldの角を丸めて表示するようBorderを設定しています。
image: https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSMYm3vgI/AAAAAAAAAiY/37FVcZLSXI0/s800/RoundedTextField.png
hreflang:
    href: https://java-swing-tips.blogspot.com/2012/03/rounded-border-for-jtextfield.html
    lang: en
---
* 概要 [#summary]
`JTextField`の角を丸めて表示するよう`Border`を設定しています。

-&jnlp;
-&jar;
-&zip;
#download(https://lh5.googleusercontent.com/_9Z4BYR88imo/TQTSMYm3vgI/AAAAAAAAAiY/37FVcZLSXI0/s800/RoundedTextField.png)

//#screenshot
#ref(http://lh5.ggpht.com/_9Z4BYR88imo/TQTSMYm3vgI/AAAAAAAAAiY/37FVcZLSXI0/s800/RoundedTextField.png)

**サンプルコード [#ecbd0878]
* サンプルコード [#sourcecode]
#code(link){{
JTextField textField01 = new JTextField(20) {
  //Unleash Your Creativity with Swing and the Java 2D API!
  //http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html
  @Override protected void paintComponent(Graphics g) {
    if(!isOpaque()) {
      int w = getWidth();
      int h = getHeight();
      Graphics2D g2 = (Graphics2D)g.create();
    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.setColor(UIManager.getColor("TextField.background"));
      g2.fillRoundRect(0, 0, w-1, h-1, h, h);
      g2.setColor(Color.GRAY);
      g2.drawRoundRect(0, 0, w-1, h-1, h, h);
      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));
  }
};
textField01.setOpaque(false);
textField01.setBackground(new Color(0,0,0,0)); //Nimbus
textField01.setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));
textField01.setText("aaaaaaaaaaa");
}}

**解説 [#sc0a1c68]
-上
--``JTextField#paintComponent(...)``をオーバーライド、``BorderをEmptyBorder``、``JTextField#setOpaque(false);``
--参考: [http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html Unleash Your Creativity with Swing and the Java 2D API!]
* 解説 [#explanation]
- 上: `Override: JTextField#paintComponent(...)`
-- `JTextField#paintComponent(...)`をオーバーライド
-- `Border`を`EmptyBorder`に変更
-- `JTextField#setOpaque(false)`を設定
-- 参考: [http://web.archive.org/web/20091205092230/http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html Unleash Your Creativity with Swing and the Java 2D API!]
-- 背景が画像などの場合でも角丸が描画可能

-下
--%%RoundTextUIを作成して、JTextField#setUI(...)で設定%%
--``RoundedCornerBorder``を設定
//--参考: [http://forums.sun.com/thread.jspa?threadID=260846 Swing - custom JTextField]
- 下: `setBorder(new RoundedCornerBorder())`
-- `RoundedCornerBorder`を設定
-- %%角を親コンポーネントの背景色で上書きしているので、背景が画像などの場合はその上に角が描画されてしまう%%
-- `JTextField`の縁と背景を透明化し、`RoundedCornerBorder`から取得した図形を描画するように修正
#code{{
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);
  }

#code{{
  @Override public void updateUI() {
    super.updateUI();
    setOpaque(false);
    setBorder(new RoundedCornerBorder());
  }
};

class RoundedCornerBorder extends AbstractBorder {
  @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);
    int r = height-1;
    RoundRectangle2D round = new RoundRectangle2D.Float(x, y, width-1, height-1, r, r);
    Container parent = c.getParent();
    if(parent!=null) {
      g2.setColor(parent.getBackground());
      Area corner = new Area(new Rectangle2D.Float(x, y, width, height));
      corner.subtract(new Area(round));
      g2.fill(corner);
    }
    g2.setColor(Color.GRAY);
    g2.draw(round);
  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.left = insets.right = 8;
    insets.top = insets.bottom = 4;
    insets.set(4, 8, 4, 8);
    return insets;
  }
}
}}

**参考リンク [#mcc5799a]
-[http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html Unleash Your Creativity with Swing and the Java 2D API!]
//-[http://forums.sun.com/thread.jspa?threadID=260846 Swing - custom JTextField]
-[http://www.coderanch.com/t/336048/GUI/java/Border-rounded-JTextField Border on an rounded JTextField? (Swing / AWT / SWT / JFace forum at JavaRanch)]
-[http://stackoverflow.com/questions/9785911/how-i-remove-unneeded-background-under-roundedborder java - how i remove unneeded background under roundedborder? - Stack Overflow]
* 参考リンク [#reference]
- [http://web.archive.org/web/20091205092230/http://java.sun.com/products/jfc/tsc/articles/swing2d/index.html Unleash Your Creativity with Swing and the Java 2D API!]
- [http://www.coderanch.com/t/336048/GUI/java/Border-rounded-JTextField Border on an rounded JTextField? (Swing / AWT / SWT / JFace forum at JavaRanch)]
- [https://stackoverflow.com/questions/9785911/how-i-remove-unneeded-background-under-roundedborder java - how i remove unneeded background under roundedborder? - Stack Overflow]

**コメント [#o62b0e9d]
- ``TextUI#paintSafely(...)``をオーバーライドして、``JTextField``内を上書きする方法はやめて、``Area#subtract``で切り抜いた図形を親の背景色で描画する方法に変更。 -- [[aterai]] &new{2012-03-21 (水) 02:37:10};
* コメント [#comment]
#comment
- `TextUI#paintSafely(...)`をオーバーライドして、`JTextField`内を上書きする方法はやめて、`Area#subtract`で切り抜いた図形を親の背景色で描画する方法に変更。 -- &user(aterai); &new{2012-03-21 (水) 02:37:10};

#comment