父对象具有背景图像时的圆形边框

时间:2015-01-09 22:42:19

标签: java graphics border background-image rounded-corners

我试图用圆角制作边框。在边框内部应该是设置边框的组件决定绘制的任何内容,并且边界之外应该是"没有&#34 ;;也就是说,它应该在那些地方绘制父组件的绘画。

我想要获得的内容:

enter image description here

我得到了什么:

enter image description here

使用蓝色边框查看容器的白色边角。我需要摆脱他们。我尝试使用自定义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

中完成所有操作

1 个答案:

答案 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();
            }
        });
    }
}

Rounded Border