我制作了自己的RoundedBorder,而不是使用圆角的LineBorder,因为我想设置圆弧大小。
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
Area area = new Area(roundRect);
g2.setColor(color);
g2.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2.setStroke(new BasicStroke(thickness));
g2.draw(area);
}
我使用border-with-rounded-corners-transparency中的一些代码来使用圆形边框之外的父背景颜色。虽然它与TitledBorder不能正常使用RoundedBorder,因为它只与RoundedBorder一起使用。将以下代码添加到我的paintBorder。
Component parent = c.getParent();
if (parent != null) {
Color bg = parent.getBackground();
Rectangle rect = new Rectangle(x, y, width, height);
Area borderRegion = new Area(rect);
borderRegion.subtract(area);
g2.setClip(borderRegion);
g2.setColor(bg);
g2.fillRect(x, y, width, height);
g2.setClip(null);
}
知道如何解决这个问题才能正常工作?
编辑:paintBorder的一个新实现让我更接近:
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
Area area = new Area(roundRect);
final Rectangle componentRect = c.getBounds();
final int componentWidth = (int) componentRect.getWidth();
final int componentHeight = (int) componentRect.getWidth();
// Paint the BG color of the parent in the entire rectangle of the component.
// Then repaint the area inside the border.
Component parent = c.getParent();
if (parent != null) {
g2.setColor(parent.getBackground());
g2.fillRect(0, 0, componentWidth, componentHeight);
g2.setColor(c.getBackground());
g2.fillRoundRect(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
}
g2.setColor(color);
g2.setRenderingHints(hints);
g2.setStroke(stroke);
g2.draw(area);
}
测试代码解决方案1:
package com.test.gui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;
import javax.swing.border.TitledBorder;
public class TestBorderApp {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestBorderApp window = new TestBorderApp();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public TestBorderApp() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainpanel = new JPanel();
JPanel panel1 = new JPanel();
panel1.setBackground(Color.RED);
RoundedBorder roundBorder1 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder1 = BorderFactory.createTitledBorder(roundBorder1,
"Title",
TitledBorder.CENTER,
TitledBorder.ABOVE_TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel1.setBorder(titleBorder1);
JLabel label1 = new JLabel("Text Text Text");
panel1.add(label1);
mainpanel.add(panel1);
JPanel panel2 = new JPanel();
panel2.setBackground(Color.RED);
RoundedBorder roundBorder2 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder2 = BorderFactory.createTitledBorder(roundBorder2,
"Title",
TitledBorder.CENTER,
TitledBorder.TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel2.setBorder(titleBorder2);
JLabel label2 = new JLabel("Text Text Text");
panel2.add(label2);
mainpanel.add(panel2);
JPanel panel3 = new JPanel();
panel3.setBackground(Color.RED);
RoundedBorder roundBorder3 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder3 = BorderFactory.createTitledBorder(
roundBorder3,
"Title",
TitledBorder.CENTER,
TitledBorder.BELOW_TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel3.setBorder(titleBorder3);
JLabel label3 = new JLabel("Text Text Text");
panel3.add(label3);
mainpanel.add(panel3);
frame.setContentPane(mainpanel);
}
public class RoundedBorder extends AbstractBorder {
private static final long serialVersionUID = -6244878594068693694L;
private Color color;
private int thickness = 4;
private int arcSize = 8;
private BasicStroke stroke;
private RenderingHints hints;
/**
* Constructor for round border
*
* @param color
* The color
* @param thickness
* The thickness
* @param arcSize
* the arc size
*/
public RoundedBorder(Color color, int thickness, int arcSize) {
this.thickness = thickness;
this.arcSize = arcSize;
this.color = color;
this.stroke = new BasicStroke(thickness);
this.hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
/**
* Set the current color of the border
*
* @param color
* The color
*/
public void setColor(Color color) {
this.color = color;
}
/**
* Get the current color of the border
*
* @return
*/
public Color getColor() {
return color;
}
public void setArcSize(int arcSize) {
this.arcSize = arcSize;
}
public int getArcSize() {
return arcSize;
}
/* (non-Javadoc)
* @see javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component, java.awt.Insets)
*/
@Override
public Insets getBorderInsets(Component c, Insets i) {
i.set(thickness, thickness, thickness, thickness);
return i;
}
/* (non-Javadoc)
* @see javax.swing.border.AbstractBorder#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
*/
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
Area area = new Area(roundRect);
// Paint the BG color of the parent, everywhere outside the clip of the text bubble.
Component parent = c.getParent();
if (parent != null) {
Color bg = parent.getBackground();
Rectangle rect = new Rectangle(x, y, width, height);
Area borderRegion = new Area(rect);
borderRegion.subtract(area);
g2.setClip(borderRegion);
g2.setColor(bg);
g2.fillRect(0, 0, width, height);
g2.setClip(null);
}
g2.setColor(color);
g2.setRenderingHints(hints);
g2.setStroke(stroke);
g2.draw(area);
}
}
}
测试代码解决方案2:
package com.test.gui;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.AbstractBorder;
import javax.swing.border.TitledBorder;
public class TestBorderApp {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TestBorderApp window = new TestBorderApp();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public TestBorderApp() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainpanel = new JPanel();
JPanel panel1 = new JPanel();
panel1.setBackground(Color.RED);
RoundedBorder roundBorder1 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder1 = BorderFactory.createTitledBorder(roundBorder1,
"Title",
TitledBorder.CENTER,
TitledBorder.ABOVE_TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel1.setBorder(titleBorder1);
JLabel label1 = new JLabel("Text Text Text");
panel1.add(label1);
mainpanel.add(panel1);
JPanel panel2 = new JPanel();
panel2.setBackground(Color.RED);
RoundedBorder roundBorder2 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder2 = BorderFactory.createTitledBorder(roundBorder2,
"Title",
TitledBorder.CENTER,
TitledBorder.TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel2.setBorder(titleBorder2);
JLabel label2 = new JLabel("Text Text Text");
panel2.add(label2);
mainpanel.add(panel2);
JPanel panel3 = new JPanel();
panel3.setBackground(Color.RED);
RoundedBorder roundBorder3 = new RoundedBorder(Color.BLACK, 5, 60);
TitledBorder titleBorder3 = BorderFactory.createTitledBorder(
roundBorder3,
"Title",
TitledBorder.CENTER,
TitledBorder.BELOW_TOP,
Font.decode(Font.SANS_SERIF),
Color.BLACK);
panel3.setBorder(titleBorder3);
JLabel label3 = new JLabel("Text Text Text");
panel3.add(label3);
mainpanel.add(panel3);
frame.setContentPane(mainpanel);
}
public class RoundedBorder extends AbstractBorder {
private static final long serialVersionUID = -6244878594068693694L;
private Color color;
private int thickness = 4;
private int arcSize = 8;
private BasicStroke stroke;
private RenderingHints hints;
/**
* Constructor for round border
*
* @param color
* The color
* @param thickness
* The thickness
* @param arcSize
* the arc size
*/
public RoundedBorder(Color color, int thickness, int arcSize) {
this.thickness = thickness;
this.arcSize = arcSize;
this.color = color;
this.stroke = new BasicStroke(thickness);
this.hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
/**
* Set the current color of the border
*
* @param color
* The color
*/
public void setColor(Color color) {
this.color = color;
}
/**
* Get the current color of the border
*
* @return
*/
public Color getColor() {
return color;
}
public void setArcSize(int arcSize) {
this.arcSize = arcSize;
}
public int getArcSize() {
return arcSize;
}
/* (non-Javadoc)
* @see javax.swing.border.AbstractBorder#getBorderInsets(java.awt.Component, java.awt.Insets)
*/
@Override
public Insets getBorderInsets(Component c, Insets i) {
i.set(thickness, thickness, thickness, thickness);
return i;
}
/* (non-Javadoc)
* @see javax.swing.border.AbstractBorder#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
*/
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
Shape roundRect = new RoundRectangle2D.Double(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
Area area = new Area(roundRect);
final Rectangle componentRect = c.getBounds();
final int componentWidth = (int) componentRect.getWidth();
final int componentHeight = (int) componentRect.getWidth();
// Paint the BG color of the parent in the entire rectangle of the component.
// Then repaint the area inside the border.
Component parent = c.getParent();
if (parent != null) {
g2.setColor(parent.getBackground());
g2.fillRect(0, 0, componentWidth, componentHeight);
g2.setColor(c.getBackground());
g2.fillRoundRect(x + thickness / 2,
y + thickness / 2,
width - thickness,
height - thickness,
arcSize,
arcSize);
}
g2.setColor(color);
g2.setRenderingHints(hints);
g2.setStroke(stroke);
g2.draw(area);
}
}}