JTextArea Rounded Corners
Asked Answered
O

2

4

I want to make JTextArea has a rounded corners, and i did this code :

public BPosTxtArea() {
    super();
    setOpaque(false);
}

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(getBackground());
    g2.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 15, 15);
    super.paintComponent(g);
}

@Override
protected void paintBorder(Graphics g) {
    Graphics2D g2 = (Graphics2D) g.create();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setColor(new Color(102, 102, 102));
    g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 15, 15);
}

but it still has a square border outside like picture bellow :

enter image description here

Can anyone help me?

Otranto answered 22/12, 2015 at 5:21 Comment(4)
Did you add the text area to a JScrollPane? Maybe you are seeing the Border of the scroll pane. Post a proper SSCCE that demonstrates the problem.Jaehne
No i just want it has rounded cornersOtranto
"i just want it has rounded corners" Just post a minimal reproducible example or SSCCE. Voting to close.Ency
Duplicate of Border with rounded corners & transparency. (Someone else will need to close it, given I added, then retracted a prior close vote, I cannot close it.)Ency
B
8

Start by having a look at How to Use Borders

This is a very simple example:

public class RoundBorder implements Border {

    private int radius;

    public RoundBorder(int radius) {
        this.radius = radius;
    }

    public int getRadius() {
        return radius;
    }

    @Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.draw(new RoundRectangle2D.Double(x, y, width - 1, height - 1, getRadius(), getRadius()));
        g2d.dispose();
    }

    @Override
    public Insets getBorderInsets(Component c) {
        int value = getRadius() / 2;
        return new Insets(value, value, value, value);
    }

    @Override
    public boolean isBorderOpaque() {
        return false;
    }

}

Rounded Border

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;

public class Example {

    public static void main(String[] args) {
        new Example();
    }

    public Example() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            JTextArea ta = new JTextArea(10, 20);
            ta.setBorder(new RoundBorder(20));

            JScrollPane sp = new JScrollPane(new JTextArea(10, 20));
            sp.setBorder(new RoundBorder(20));

            add(ta, gbc);
            add(sp, gbc);
        }

    }

    public class RoundBorder implements Border {

        private int radius;

        public RoundBorder(int radius) {
            this.radius = radius;
        }

        public int getRadius() {
            return radius;
        }

        @Override
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.draw(new RoundRectangle2D.Double(x, y, width - 1, height - 1, getRadius(), getRadius()));
            g2d.dispose();
        }

        @Override
        public Insets getBorderInsets(Component c) {
            int value = getRadius() / 2;
            return new Insets(value, value, value, value);
        }

        @Override
        public boolean isBorderOpaque() {
            return false;
        }

    }

}

Problems, the border is painted "within" the component fill area, meaning that the corners will be the same color as the fill area. There's no way around it using Border.

The trick would be to create a second component, onto which you could paint the border (via the paintComponent, filling the area within the border the same color as the text area) and then add the component into that.

Updated

Based on you code example, you're not overriding getInsets, which is going to be very important, the other thing is, it appears that your JTextArea is within a JScrollPane...

Comparison

public class BPosTextArea extends JTextArea {

    private int radius;

    public BPosTextArea() {
        super(10, 20);
        setOpaque(false);
        setBorder(null);
        setRadius(20);
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(getBackground());
        g2.fillRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
        super.paintComponent(g);
    }

    @Override
    protected void paintBorder(Graphics g) {
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(new Color(102, 102, 102));
        g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, getRadius(), getRadius());
    }

    public void setRadius(int radius) {
        this.radius = radius;
        repaint();
    }

    public int getRadius() {
        return radius;
    }

    @Override
    public Insets getInsets() {
        int value = getRadius() / 2;
        return new Insets(value, value, value, value);
    }

}

A solution is to set the border to null for the JScrollPane

Beatrizbeattie answered 22/12, 2015 at 6:3 Comment(2)
I did setBorder to null and overriding method getInsets but there's no change. Is there any other way to remove JScrollPane ?Otranto
You don't want to remove the JScrollPane, setting the JScrollPane's border to null "should" remove it. You may also need to make the JScrollPane's JViewport transparent as well as the JScrollPane itselfBeatrizbeattie
M
0

Your code is fine, the detail is that JTextArea is linked to a JScrollPane which is adding that border to your TextArea, I corrected it this way. You must check what scrollpane is linked to once identified in the constructor of your class you must add this.

 jScrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));

and your textarea will look like this:

example

You can give more style to your scroll but that is already separate.

Millinery answered 24/5, 2023 at 17:3 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.