5 votes

Java : créer une région de découpe avec un trou ?

Comment définissez-vous une région de découpage (via Graphics2D.clip(Shape)) qui a un trou dedans?

par exemple : un Rectangle r1 moins un autre Rectangle r2 à l'intérieur de r1

Je suis sûr qu'il y a une réponse simple, mais je ne trouve pas.

4voto

Jason S Points 58434

Path2D.append() + règle de vent WIND_EVEN_ODD semblent faire l'affaire:

saisir la description de l'image ici

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);
    }
}

2voto

jzd Points 17369

Il semble que cela ne soit pas pris en charge par Graphics's setClip. D'après ce que je lis dans la documentation, seul un rectangle est pris en charge:

public abstract void setClip(Shape clip)

Définit la région de découpe actuelle sur une forme de découpe arbitraire. Tous les objets qui implémentent l'interface Shape ne peuvent pas être utilisés pour définir la découpe. Les seuls objets Shape garantis d'être pris en charge sont les objets Shape obtenus via la méthode getClip et via des objets Rectangle. Cette méthode définit la découpe utilisateur, indépendamment de la découpe associée aux limites du périphérique et à la visibilité de la fenêtre.

1voto

Ernest Friedman-Hill Points 56605

La classe GeneralPath est une implémentation de Shape qui peut représenter des formes avec des trous. Vous définissez plusieurs segments de trajet, l'un représentant "l'extérieur", et l'autre représentant "le trou". Définissez la région de découpe souhaitée en utilisant GeneralPath, puis appelez clip().

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X