我试图用圆角制作边框。在边框内部应该是设置边框的组件决定绘制的任何内容,并且边界之外应该是"没有&#34 ;;也就是说,它应该在那些地方绘制父组件的绘画。
我想要获得的内容:
我得到了什么:
使用蓝色边框查看容器的白色边角。我需要摆脱他们。我尝试使用自定义Border
:
public class RoundedLineBorder extends AbstractBorder {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(
0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(
0, 0, width, height);
Area borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
parentArea.subtract(borderArea);
Component parent = c.getParent();
if (parent != null) {
g2.setColor(parent.getBackground());
/* fill parent background color outside borders */
g2.setClip(parentArea);
g2.fillRect(fullRect);
g2.setClip(null);
}
g2.setColor(Color.blue);
/* draw borders */
g2.draw(borderArea);
}
}
当父组件具有纯色背景但是如果它具有背景图像时,这可以正常工作 它当然不是。有没有办法获得真实的颜色 上述地方?
有没有更好的方法来实现圆形边框而不实际扩展JPanel
并在其paintComponent
?
答案 0 :(得分:1)
它需要边框和组件之间的紧密耦合,
您可以创建容器组件来执行此操作,这样您就不需要自定义每个组件。
类似的东西:
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import javax.swing.border.*;
public class RoundedBorderContainer extends JPanel implements Border
{
private boolean componentWasOpaque;
public RoundedBorderContainer(JComponent component)
{
setLayout( new BorderLayout() );
add( component );
componentWasOpaque = component.isOpaque();
component.setOpaque( false );
setOpaque( false );
setBorder( this );
}
@Override
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
int width = getWidth();
int height = getHeight();
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width, height, arc, arc);
g2.setClip(borderRect);
super.paint(g);
super.paintBorder(g);
g2.setClip( null );
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (componentWasOpaque)
{
g.setColor(getComponent(0).getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
}
}
@Override
public Insets getBorderInsets(Component c)
{
return new Insets(1, 1, 1, 1);
}
@Override
public boolean isBorderOpaque()
{
return false;
}
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height)
{
Graphics2D g2 = (Graphics2D) g;
int arc = 20;
RoundRectangle2D borderRect = new RoundRectangle2D.Double(0, 0, width - 1, height - 1, arc, arc);
Rectangle fullRect = new Rectangle(0, 0, width, height);
Area borderArea = new Area(borderRect);
borderArea = new Area(borderRect);
Area parentArea = new Area(fullRect);
g2.setColor(Color.RED);
g2.draw(borderArea);
}
private static void createAndShowGUI()
{
JLabel label = new JLabel( new ImageIcon("grass.jpg") );
label.setLayout( new GridBagLayout() );
JPanel panel = new JPanel();
panel.setPreferredSize( new Dimension(100, 100) );
panel.setBackground( Color.BLACK );
// JLabel panel = new JLabel( new ImageIcon("???") );
RoundedBorderContainer rbc = new RoundedBorderContainer(panel);
label.add(rbc);
JFrame frame = new JFrame("Rounded Border");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( label );
frame.setLocationByPlatform( true );
// frame.pack();
frame.setSize(400, 400);
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}