Java: создать область отсечения, в которой есть отверстие? - PullRequest
5 голосов
/ 08 июня 2011

Как определить регион отсечения (через Graphics2D.clip(Shape)), в котором есть отверстие?

например: прямоугольник r1 минус другой прямоугольник r2 внутри r1

Я уверен, что это простой ответ, но я рисую пробел.

Ответы [ 3 ]

4 голосов
/ 08 июня 2011

Path2D.append() + правило извлечения EVEN_ODD, кажется, делает трюк:

enter image description here

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 голосов
/ 08 июня 2011

Похоже, это не поддерживается графикой setClip.Когда я читаю документацию, прямоугольник - это все, что поддерживается:

public abstract void setClip (Shape clip)

Устанавливает текущую область отсечения в произвольнуюформа клипа.Не все объекты, которые реализуют интерфейс Shape, могут быть использованы для установки клипа.Единственными объектами Shape, которые гарантированно поддерживаются, являются объекты Shape, полученные с помощью метода getClip и с помощью объектов Rectangle. Этот метод устанавливает пользовательский клип, который не зависит от отсечения, связанного с границами устройства и окном.видимость.

1 голос
/ 08 июня 2011

Класс GeneralPath является реализацией Shape, которая может представлять фигуры с отверстиями в них.Вы определяете несколько сегментов пути, один из которых представляет «снаружи», а другой представляет «дыру».Определите область отсечения, которую вы хотите, используя GeneralPath, а затем вызовите clip().

...