Java: create clipping region that has a hole?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-10 14:58:10

问题


How do you define a clipping region (via Graphics2D.clip(Shape)) that has a hole in it?

for example: a Rectangle r1 minus another Rectangle r2 inside r1

I'm sure this has an easy answer, but I'm drawing a blank.


回答1:


Path2D.append() + EVEN_ODD winding rule appear to do the trick:

package com.example.test.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class HoleClipper extends JPanel
{
    @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        Rectangle2D r1 = getBounds();
        int margin = 50;
        Rectangle2D r2 = new Rectangle2D.Double(
                r1.getMinX()+margin,
                r1.getMinY()+margin,
                r1.getWidth()-2*margin,
                r1.getHeight()-2*margin);

        g2d.setColor(Color.YELLOW);
        g2d.fill(r1);

        Path2D p = new Path2D.Double(Path2D.WIND_EVEN_ODD);
        p.append(r1, false);
        p.append(r2, false);
        g2d.clip(p);

        int spacing = 10;
        g2d.setColor(Color.BLACK);
        for (double d = 0; d < r1.getWidth() + r1.getHeight(); d += spacing)
        {
            Line2D line = new Line2D.Double(0, d, d, 0);
            g2d.draw(line);
        }
    }

    public static void main(String[] args) {
        HoleClipper clipper = new HoleClipper();
        clipper.setPreferredSize(new Dimension(300, 200));

        JFrame frame = new JFrame("HoleClipper");
        frame.setContentPane(clipper);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}



回答2:


Looks like this is not supported by Graphics's setClip. As I read the documentation a rectangle is all that is supported:

public abstract void setClip(Shape clip)

Sets the current clipping area to an arbitrary clip shape. Not all objects that implement the Shape interface can be used to set the clip. The only Shape objects that are guaranteed to be supported are Shape objects that are obtained via the getClip method and via Rectangle objects. This method sets the user clip, which is independent of the clipping associated with device bounds and window visibility.




回答3:


The GeneralPath class is an implementation of Shape that can represent shapes with holes in them. You define multiple path segments, one representing the "outside", and one representing the "hole". Define the clipping region you want using GeneralPath, and then call clip().



来源:https://stackoverflow.com/questions/6280823/java-create-clipping-region-that-has-a-hole

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!