Inside clipping with Java Graphics

我们两清 提交于 2019-11-30 18:47:12

You need to use the Area class. This example will demonstrate how to do what you ask:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Test extends JPanel {

    public static void main(String[] args) {
        JFrame f = new JFrame();
        Test t = new Test();
        f.getContentPane().setLayout(new BorderLayout());
        f.getContentPane().add(t,BorderLayout.CENTER);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }

    public Test() {
        setPreferredSize(new Dimension(300, 300));
    }

    public void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g.create();
        Rectangle2D rectangleNotToDrawIn = new Rectangle2D.Double(100, 100, 20, 30);
        Area outside = calculateRectOutside(rectangleNotToDrawIn);
        g2.setPaint(Color.white);
        g2.fillRect(0, 0, getWidth(), getHeight());
        g2.setPaint(Color.black);
        g2.setClip(outside);
        g2.drawLine(0, 0, getWidth(), getHeight());

    }


    private Area calculateRectOutside(Rectangle2D r) {
        Area outside = new Area(new Rectangle2D.Double(0, 0, getWidth(), getHeight()));
        outside.subtract(new Area(r));
        return outside;
    }

}

You can do this with an AWT clip. You'll need to know the bounds of the rectangle you want to exclude, and the outer bounds of your drawing area.

The following demo code opens a frame and displays a single panel in it. The panel's paint method sets up an example clip which looks like a rectangle with a rectangular hole in the middle, when in fact it's a polygon that describes the area around the area we want to exclude. The clip rectangle should be composed of the bounds of the excluded rectangle, and the outer edge of the drawing area, but I've left hard-coded values in to keep it simple and illustrate the workings better (I hope!)

+-------------------+
| clip drawing area |
+---+-----------+   |
|   | excluded  |   |
|   |   area    |   |
|   +-----------+   |
|                   |
+-------------------+

This method has the benefit over calculating the line intersection manually in that it prevents all AWT painting going into the excluded area. I don't know if that's useful to you or not.

My demo then paints a black rectangle over the whole area, and a single white diagonal line running through it, to illustrate the clip working.

public class StackOverflow extends JFrame {
    public static void main(String[] args) {
        new StackOverflow();
    }

    private StackOverflow() {
        setTitle( "Clip with a hole" );
        setSize( 320,300 );
        getContentPane().add( new ClipPanel() );
        setVisible( true );
    }
}

class ClipPanel extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        Polygon clip = new Polygon(
                new int[]{ 0, 100, 100,  0,  0, 20, 20, 80, 80,  0 },
                new int[]{ 0,   0,  60, 60, 20, 20, 40, 40, 20, 20 },
                10
            );
        g.setClip(clip);
        g.setColor( Color.BLACK );
        g.fillRect( 0,0,100,60 );
        g.setColor( Color.WHITE );
        g.drawLine( 0,0,100,60 );
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!