使用 Java Graphics 进行内部剪裁

发布于 2024-07-30 13:27:03 字数 95 浏览 2 评论 0原文

我需要使用 java.awt.Graphics 绘制一条线,但只应渲染位于矩形之外的线部分。

是否可以使用图形剪切支持,或者我是否需要自己计算交集并剪切线?

I need to draw a line using java.awt.Graphics, but only the portion of the line that lies outside of a rectangle should be rendered.

Is it possible to use the Graphics clipping support or do I need to calculate the intersection and clip the line myself?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

囍笑 2024-08-06 13:27:03

您需要使用 Area 类。 此示例将演示如何执行您所要求的操作:

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

}
绾颜 2024-08-06 13:27:03

您可以使用 AWT 剪辑来完成此操作。 您需要知道要排除的矩形的边界以及绘图区域的外边界。

以下演示代码打开一个框架并在其中显示一个面板。 面板的绘制方法设置了一个示例剪辑,它看起来像一个中间有一个矩形孔的矩形,而实际上它是一个多边形,描述了我们要排除的区域周围的区域。 剪辑矩形应由排除矩形的边界和绘图区域的外边缘组成,但我保留了硬编码值以保持简单并更好地说明工作原理(我希望!)

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

此方法具有与手动计算线相交相比的好处是,它可以防止所有 AWT 绘画进入排除区域。 我不知道这对你是否有用。

然后,我的演示在整个区域上绘制一个黑色矩形,并穿过它一条白色对角线,以说明剪辑的工作原理。

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

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 );
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文