JavaFX剪辑产生一个';彩票刮刮票'-影响

JavaFX剪辑产生一个';彩票刮刮票'-影响,java,canvas,javafx,graphicscontext,Java,Canvas,Javafx,Graphicscontext,我开始玩JavaFXGraphicsContext。 特别是剪辑部分对我来说很有趣 因此,我尝试创建一些图形,并为其创建一个剪切遮罩(一个简单的矩形,可以四处移动) 但是我注意到它有一些奇怪的行为(不确定这是一个bug还是由于错误的代码使用) 下面您可以找到一个示例应用程序来说明问题 描述我对代码的期望: 带有洋红矩形和文本的白色画布,该矩形仅在洋红上方可见(尽管它被画过) 实际上,这正是您首先看到的 当您移动应用程序窗口时,洋红色矩形会四处移动(如预期的那样)!但仿古白色填充变得可见(这是我从

我开始玩
JavaFX
GraphicsContext
。 特别是剪辑部分对我来说很有趣

因此,我尝试创建一些图形,并为其创建一个剪切遮罩(一个简单的矩形,可以四处移动)

但是我注意到它有一些奇怪的行为(不确定这是一个bug还是由于错误的代码使用)

下面您可以找到一个示例应用程序来说明问题

描述我对代码的期望: 带有洋红矩形和文本的白色画布,该矩形仅在洋红上方可见(尽管它被画过)

实际上,这正是您首先看到的

当您移动应用程序窗口时,洋红色矩形会四处移动(如预期的那样)!但仿古白色填充变得可见(这是我从未预料到的),任何曾经被洋红覆盖的区域现在都可见(无剪裁)

古董白色和洋红色的东西,是用来使它更明显的东西是错的。由于整个画布在开始时已清除,并且仅完成了一次剪裁,因此重新绘制(或在旧图形上绘制)时不应出现问题

启动应用程序并将其四处移动,以查看“彩票刮刮”效果

public class ClippingExampleApp extends Application {

    private boolean clip = true;
    private static Bounds clippingArea = new BoundingBox(100, 50, 300, 300);

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Clipping Test App");
        primaryStage.setX(100);
        primaryStage.setY(50);

        Group root = new Group();
        Canvas canvas = new Canvas(640, 480);
        root.getChildren().add(canvas);
        primaryStage.setScene(new Scene(root));

        ChangeListener<Number> updateBounds = new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> arg0, Number arg1, Number arg2) {
                clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300);
                draw(canvas, clip);
            }
        };
        primaryStage.yProperty().addListener(updateBounds);
        primaryStage.xProperty().addListener(updateBounds);
        primaryStage.widthProperty().addListener(updateBounds);
        primaryStage.heightProperty().addListener(updateBounds);

        primaryStage.show();
        clippingArea = new BoundingBox(primaryStage.getX(), primaryStage.getY(), 300, 300);
        draw(canvas, clip);
    }

    private static void draw(Canvas canvas, boolean clip) {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        // CLEAR THE COMPLETE CANVAS
        gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
        gc.save();
        if (clip) {
            // clipping rect
            gc.rect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight());
            gc.clip();

            // fill the whole background (this should only affect the clipped
            // area 
            gc.setFill(Color.ANTIQUEWHITE);
            gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            // this should overlap the Color.ANTIQUEWHITE - so no ANTIQUEWHITE is visible
            gc.setFill(Color.MAGENTA);
            gc.fillRect(clippingArea.getMinX(), clippingArea.getMinY(), clippingArea.getWidth(), clippingArea.getHeight());

            // finally fill the text, which sould only be visible where the magenta rect is...
            String text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.";
            gc.setFill(Color.BLACK);
            gc.fillText(text, 50, 100);
        }
        gc.restore();
    }
}
public类ClippingExampleApp扩展应用程序{
私有布尔剪辑=真;
私有静态边界clippingArea=新边界框(100,50,300,300);
公共静态void main(字符串[]args){
发射(args);
}
@凌驾
公共无效开始(阶段primaryStage){
primaryStage.setTitle(“剪辑测试应用程序”);
初级阶段:setX(100);
初生阶段:setY(50);
组根=新组();
画布=新画布(640480);
root.getChildren().add(画布);
primaryStage.setScene(新场景(根));
ChangeListener updateBounds=新的ChangeListener(){
@凌驾
公共空隙发生了变化(可观察值

请注意,当前路径不会恢复

因此,您进行的所有
gc.rect()
调用都会累积到一个用作片段的路径中

如果你加上

gc.beginPath();
要清除if(clip)
块开头的路径,您将看到我认为您期望的行为。

从:

请注意,当前路径不会恢复

因此,您进行的所有
gc.rect()
调用都会累积到一个用作片段的路径中

如果你加上

gc.beginPath();

清除
if(剪辑)开头的路径
block,你看到了我认为你期待的行为。

你的问题是什么?显然,问题是如何纠正这种奇怪的行为,并将区域裁剪为洋红色。你的问题是什么?显然,问题是如何纠正这种奇怪的行为,并将区域裁剪为洋红色谢谢!实际上,我认为ath在每次绘制后都会被清除-不需要beginPath。谢谢!事实上,我认为路径在每次绘制后都会被清除-而beginPath是不需要的。