JTextArea 圆角
JTextArea Rounded Corners
我想让 JTextArea 有一个圆角,我做了这个代码:
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);
}
但它的外面仍然有一个方形边框,如下图所示:
谁能帮帮我?
这是一个非常简单的例子:
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;
}
}
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;
}
}
}
问题,边框是画"within"组件填充区域的,也就是说边角会和填充区域颜色一样。没有办法使用 Border
.
诀窍是创建第二个组件,您可以在其上绘制边框(通过 paintComponent
,用与文本区域相同的颜色填充边框内的区域),然后添加该组件进入那个。
已更新
根据您的代码示例,您没有覆盖 getInsets
,这将非常重要,另一件事是,您的 JTextArea
似乎在 JScrollPane
...
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);
}
}
一个解决方案是将 border
设置为 null
用于 JScrollPane
我想让 JTextArea 有一个圆角,我做了这个代码:
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);
}
但它的外面仍然有一个方形边框,如下图所示:
谁能帮帮我?
这是一个非常简单的例子:
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;
}
}
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;
}
}
}
问题,边框是画"within"组件填充区域的,也就是说边角会和填充区域颜色一样。没有办法使用 Border
.
诀窍是创建第二个组件,您可以在其上绘制边框(通过 paintComponent
,用与文本区域相同的颜色填充边框内的区域),然后添加该组件进入那个。
已更新
根据您的代码示例,您没有覆盖 getInsets
,这将非常重要,另一件事是,您的 JTextArea
似乎在 JScrollPane
...
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);
}
}
一个解决方案是将 border
设置为 null
用于 JScrollPane