当前位置: 首页 > 知识库问答 >
问题:

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

裴鸿熙
2023-03-14

我试图用圆角做一个边框。边框内应该是设置边框的组件决定绘制的任何内容,边框外应该“没有”;也就是说,它应该在这些地方绘制父组件的油漆。

我想得到的是:

我得到的是:

看到带有蓝色边框的容器的白色角落。我需要摆脱它们。我正在尝试使用自定义边界来实现这一点:

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,只需在其绘画组件中完成所有操作?

共有1个答案

桂和同
2023-03-14

它需要边框和组件之间的紧密耦合,

您可以创建一个容器组件来执行此操作,这样就不需要自定义每个组件。

类似于:

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();
            }
        });
    }
}
 类似资料:
  • 我试着让两个div相邻,它们之间有一个对角线空间。我在stackoverflow上看到过多个关于对角线div的教程,但它们都是通过为带有纯色的div使用两个边框并使用它们创建的对角线来实现的。但我想要图片/背景图像,而不是纯色。甚至可能还有其他内容,比如在对角线下的文本。当使用边框时,这是不可能的,因为边框在div之外。(floatright隐藏溢出或其他内容。) 这里有人能给我一个提示如何实现这

  • 问题内容: 如何在JPANEL上放置图像背景? 问题答案: 这是一个解释。

  • 如何设计带有圆角和透明解雇按钮的自定义警报对话框?

  • 我想制作圆角对话框;但是在我完成后,它出现了这样的 爪哇 XML 问题是:为什么对话框仍然显示在没有角半径的背景中? 在寻找这个问题的解决方案后,我找到了一些解决方案 1-Android对话框-圆角和透明度 2-带有圆角的Android自定义警报对话框 3-带圆角的Android对话框背景有分层背景 Java-测试上述解决方案后 测试解决方案后的结果 现在对话框根本没有出现!任何人都可以给我解决这

  • 我有一个带有平铺背景图像和边框图像的Div。边框图像是带有角设计的透明. png,所以边框周围大约有90像素厚。IE在边框内启动背景图像,其中FF、Chrome和Safari在边框的外部边缘启动背景图像。在IE中,这会导致背景颜色(或主体的背景)通过透明. png边框图像显示。我尝试了背景剪辑和位置,让IE从边框外部开始背景图像,但没有运气。 我错过了什么或建议吗?样品现在就直播@样品 } 父对象

  • 我有一个angular项目,其中有一个大的背景图像,填充页面,还有一个简单的侧边栏,其中包含链接,单击后,会将背景的url更改为另一个图像(来自cdn)。由于这些图像相当大,需要一两秒钟才能加载,这很明显,我想添加一个预加载程序,但我不确定如何在angular 2中完成。 在我的html中,我有这个: 变量urlImage填充在组件的构造函数中,侧栏链接在单击时用一个简单的函数改变它的值,如下所示