如何在java中用普通矩形轮廓绘制圆角矩形

2024-01-15

对于我的 java 应用程序,我需要一个圆角矩形,其轮廓看起来像普通矩形,如下所示

我知道你可以通过在其中绘制一个普通矩形和一个 RoundRect 来实现这一点,但我不想在其中绘制一个 RoundRect 因为我想在其中绘制其他内容。

所以是一个带有正常角的圆矩形。我如何在Java中绘制它?

The problem is that the rectangle looks like this if I use layers: enter image description hereThe corners are filled up with the wrong color. How do I prevent that?


我可以想到两种方法。首先是生成一个Shape代表方形外边缘和圆形内边缘。

第二种是使用AlphaComposite生成屏蔽结果。

public class TestMask {

    public static void main(String[] args) {
        new TestMask();
    }

    public TestMask() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new MaskedPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class MaskedPane extends JPanel {

        public MaskedPane() {
            setBackground(Color.RED);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            BufferedImage outter = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = outter.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.BLACK);
            g2d.fillRect(0, 0, getWidth(), getHeight());
            g2d.dispose();
            BufferedImage inner = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
            g2d = inner.createGraphics();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.BLACK);
            g2d.fillRoundRect(10, 10, getWidth() - 20, getHeight() - 20, 20, 20);
            g2d.dispose();

            BufferedImage masked = applyMask(outter, inner, AlphaComposite.DST_OUT);
            g.drawImage(masked, 0, 0, this);

        }

        public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
            BufferedImage maskedImage = null;
            if (sourceImage != null) {

                int width = maskImage.getWidth();
                int height = maskImage.getHeight();

                maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                Graphics2D mg = maskedImage.createGraphics();

                int x = (width - sourceImage.getWidth()) / 2;
                int y = (height - sourceImage.getHeight()) / 2;

                mg.drawImage(sourceImage, x, y, null);
                mg.setComposite(AlphaComposite.getInstance(method));
                mg.drawImage(maskImage, 0, 0, null);
                mg.dispose();
            }

            return maskedImage;
        }

        public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage) {
            return (BufferedImage) applyMask(sourceImage, maskImage, AlphaComposite.DST_IN);
        }
    }
}

更新了形状示例

终于有时间去打一发了...

public class TestMask {

    public static void main(String[] args) {
        new TestMask();
    }

    public TestMask() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ShapedPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ShapedPane extends JPanel {

        public ShapedPane() {
            setBackground(Color.GREEN);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setColor(Color.BLACK);
            g2d.fill(new RounedFrame(getWidth(), getHeight(), 10, 20));
            g2d.dispose();
        }
    }

    public class RounedFrame extends Path2D.Float {

        public RounedFrame(float width, float height, float thickness, float radius) {

            moveTo(0, 0);
            lineTo(width, 0);
            lineTo(width, height);
            lineTo(0, height);
            lineTo(0, 0);

            float innerWidth = width - thickness;
            float innerHeight = height - thickness;

            moveTo(thickness + radius, thickness);
            lineTo(innerWidth - radius, thickness);

            curveTo(innerWidth, thickness, innerWidth, thickness, innerWidth, thickness + radius);

            lineTo(innerWidth, innerHeight - radius);
            curveTo(innerWidth, innerHeight, innerWidth, innerHeight, innerWidth - radius, innerHeight);
            lineTo(thickness + radius, innerHeight);
            curveTo(thickness, innerHeight, thickness, innerHeight, thickness, innerHeight - radius);
            lineTo(thickness, thickness + radius);
            curveTo(thickness, thickness, thickness, thickness, thickness + radius, thickness);

            closePath();

            setWindingRule(WIND_EVEN_ODD);

        }
    }
}

Updated

根据安德鲁的评论,您可以通过使用来简化形状示例的使用Area

你可以更换paintComponent从上面这个例子来看......

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Area area = new Area(new Rectangle(0, 0, getWidth(), getHeight()));
    area.subtract(new Area(new RoundRectangle2D.Float(10, 10, getWidth() - 20, getHeight() - 20, 20, 20)));

    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setColor(Color.BLACK);
    g2d.fill(area);
    g2d.dispose();
}

哪个更简单:D

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在java中用普通矩形轮廓绘制圆角矩形 的相关文章

随机推荐

  • 如何更改基于 autotools 的 Bitbake 配方的安装路径?

    我有一个基于自动工具的 BitBake 配方 我想将其安装在其中 usr local bin和安装的库 usr local lib 代替 usr bin and usr lib 这是默认目标目录 这是其中的一部分autotools bbcl
  • Ansible vars_prompt 角色

    我有一套Ansibleplaybooks 和主 yml 文件是这样的 hosts all roles common install nginx 我想在触发剧本时添加确认消息 我尝试了这个但没有成功 hosts all vars prompt
  • 为什么没有 2 字节浮点并且已经存在实现?

    假设我真的内存不足并且想要更小的范围 类似于short vs int 着色器语言已经支持half对于半精度的浮点类型 不仅仅是来回转换使值在 1 和 1 之间 即返回一个像这样的浮点数 shortComingIn maxRangeOfSho
  • Spring管理事务@Transactional注解

    传播设置是必需的 Transactional propagation Propagation REQUIRED 事务是读 写的 它们在什么场景下使用 请给我举例说明 Spring事务默认是 Transactional propagation
  • Mapkit 引脚颜色未改变

    我正在执行以下操作并始终获得绿色引脚 pin pinColor MKPinAnnotationColorRed self mapView addAnnotation pin pin release pin 的类型为 NSObject 所有引
  • 从 python 列表对象和单引号中删除前缀

    这是我的清单 Volume vol b81a2cb0 Volume vol ab2b1ba3 Volume vol fc2c1cf4 我希望它看起来像这样 vol b81a2cb0 vol ab2b1ba3 vol fc2c1cf4 所以应
  • 如何创建具有不同线型的主网格线和次网格线

    我目前正在使用matplotlib pyplot创建图表 并希望主要网格线为实线和黑色 次要网格线为灰色或虚线 在网格属性中 which both major mine 然后简单地通过 linestyle 定义颜色和线型 有没有办法只指定次
  • 在 jQuery 中做什么...... var myVar = $( [] ); ......做?

    var myVar 这个 jQuery 是做什么的 它是否将变量初始化为空的 jQuery 集 我搜索了 jQuery 文档 但没有找到此语法的解释 摘自 jQuery 文档http api jquery com jQuery http a
  • 仅适用于 Word 桌面版的 Office 加载项

    我正在开发 Word 加载项 并且使用 Word Online 中仍然不支持的内容控件编辑 我还使用 Word Online 中也不支持的 Binding bindingDataChanged 事件 如果没有使用这些功能的功能 则该加载项对
  • jQuery:添加元素直到达到特定高度

    我左边有一个专栏 里面有几篇文章 该高度是动态的 并根据发布的内容而变化 我的右侧有一列通常较短 我拉出 3 个大元素 然后拉出另外 5 个小元素 我想用额外的元素填充右列 直到它接近左列的高度 所以我拉出所有大元素 3 并假设它比左边短
  • 当我切换设备时 Android Logcat 不显示日志

    我正在尝试使用 Logcat 来帮助诊断我的 Android 问题 我经常插入手机并运行模拟器 有时我在模拟器上调试 有时我在手机上调试 甚至可能在第三个设备上调试 设备切换后 Logcat 不会继续显示消息 如何指定 Logcat 的功能
  • 为什么 Haskell 中没有 `Cofunctor` 类型类?

    单子得到fmap from Functor类型类 为什么 comonad 不需要cofmap方法定义在Cofunctor class Functor定义为 class Functor f where fmap a gt b gt f a g
  • 如何设置音频时长

    我正在尝试使用音频的 HTML DOM 持续时间属性设置音频标签的持续时间 我已尝试以下方法 但似乎不起作用 audio 0 duration 1 我已经浏览了其他答案 但我看不到任何使用持续时间属性的答案 如果持续时间属性是只读的 它还给
  • 无法在 Symfony 3 中找到模板

    我知道有很多类似的主题 但我没有找到解决方案 我有这个问题 无法找到模板 CoreBundle index html twig 查看 var www html MyProject vendor symfony symfony src Sym
  • 无法删除动态添加的脚本

    我正在附加一个子元素 其中引用了 javascript 和样式表 但我想在不再使用它时再次删除它 var head document getElementsByTagName head 0 We create the style var s
  • 为什么我收到未定义的方法“cookies”?

    我正在尝试为我的 Rails 后端应用程序设置 Authlogic 和 single access token 我正在使用rails api gem 我正在遵循这个例子 http blog centresource com 2013 06
  • PHP 中舍入的最佳方法

    我有一个表格 当用户填写他们拥有的瓶子总数时 它会插入数据库 然后总结有多少箱 例如 在葡萄酒中 有 12 个瓶箱 如果用户放入 100 个瓶子 则应将其除以 12 得出总和 8 33333333 bottles 100 将其四舍五入为数字
  • 如何确定mxgraph中连接的哪一侧已连接

    我遇到这样的问题 一个决定有 3 个方面Input Yes No 我想确定箭头连接到其中的哪一个 这是我要连接的方式 从 是 连接 问题 如何知道连接是否已连接Input Yes No sides Note 如果问题可以通过内置菱形解决 那
  • 无法从 Firebase 检索图像

    我正在尝试构建一个信使类型的应用程序 为此 我将手机中的图像上传到 Firebase 该图像已成功存储在 Firebase 存储中 我正在尝试在手机上显示图像 我使用 Picasso 和 Glide 从 Firebase 检索图像 但我的照
  • 如何在java中用普通矩形轮廓绘制圆角矩形

    对于我的 java 应用程序 我需要一个圆角矩形 其轮廓看起来像普通矩形 如下所示 我知道你可以通过在其中绘制一个普通矩形和一个 RoundRect 来实现这一点 但我不想在其中绘制一个 RoundRect 因为我想在其中绘制其他内容 所以