Google Tag Manager

2012/03/21

Rounded Border for JTextField

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);
  }
  @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;
  }
}

References

18 comments:

  1. This is great! Thank you for taking the time to post...definitely helped me understand things better.

    ReplyDelete
    Replies
    1. Glad to be of help :)
      # I think java.awt.geom.Area is very useful in this case.

      Delete
  2. very help full for me thanks alot

    ReplyDelete
  3. hello, I have a question
    when I put a background image on a JLabel, JTextField appears as if the edges not disappeared, is still seen as a square background.
    In your case you do not notice that you use the same GUI
    how could I fix it?

    ReplyDelete
    Replies
    1. Hello,
      Thanks for reporting. I will put a fix for this.

      Delete
  4. class RoundedBorder implements Border {
    int radius;
    RoundedBorder(int radius) {
    this.radius = radius;
    }
    public Insets getBorderInsets(Component c) {
    return new Insets(this.radius+1, this.radius+1, this.radius+2, this.radius);
    }
    public boolean isBorderOpaque() {
    return false;
    }
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    g.setColor(Color.BLACK);
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
    g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
    g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
    g2d.drawRoundRect(x,y,width-1,height-1,radius+2,radius+2);
    g2d.dispose();

    }


    }


    this is my code but still the corners are visible

    ReplyDelete
    Replies
    1. Hi, Shriya
      Maybe you should be using JTextField#setOpaque(false).

      https://gist.github.com/aterai/249d41a625ffbbf2c91729a6bc504fd4

      JTextField textField02 = new JTextField("bbbbbbbbbbbbbbb") {
      @Override protected void paintComponent(Graphics g) {
      Border border = getBorder();
      if (!isOpaque() && border instanceof RoundedBorder) {
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setPaint(getBackground());
      g2.fill(((RoundedBorder) border).getBorderShape(0, 0, getWidth() - 1, getHeight() - 1));
      g2.dispose();
      }
      super.paintComponent(g);
      }
      };
      textField02.setOpaque(false);
      textField02.setBorder(new RoundedBorder(10));

      Delete
  5. Replies
    1. Thanks for the comment, and I'm sorry I overlooked it...

      Delete
  6. Hola Jorge,
    > en donde tengo que poner este codigo?
    Puede colocarlo en el mismo directorio si usa el mismo paquete que el código que desea usar.
    Si es problemático, puede agregarlo al mismo archivo.

    ReplyDelete
  7. Hello aterai,
    First, I want to thank you for this amazing work
    I try to use it with JComboBox and JScrollPane but the corners still visible
    I know you make it for JTextField, but if there is a way to use with them, I will be very blessed to you
    Thanks in advance

    ReplyDelete
    Replies
    1. Hi Unknown,

      JComboBox: How about using the BasicComboBoxUI https://ateraimemo.com/Swing/RoundedDropDownList.html

      Delete
    2. Thanks for the fast response, I will try it

      Delete
  8. Can I do it with jformattedtextfield?
    How then?

    ReplyDelete
    Replies
    1. Yes, JFormattedTextField inherits from JTextField, so you can do that as well.

      ex.
      JFormattedTextField f = new JFormattedTextField(NumberFormat.getNumberInstance()) {
      @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());
      }
      };

      Delete
    2. Yes it works fine. Thanks so much, good work

      Delete