java - 调整减法形状的大小

标签 java javafx shapes

我想调整下面创建的形状的大小。但无法得到它。 该项目是创建一个透明矩形,仅显示桌面的一部分,并隐藏其余部分。透明区域是减法的结果,我需要让用户调整它的大小。

我尝试了多种方法,例如从此改编:https://gist.github.com/jewelsea/1441960

但无法获取。

这是我的代码:

@Override
public void start(Stage stage) {
    Group group = new Group();
    Rectangle rect = new Rectangle(0, 0, 350, 300);
    Rectangle clip = new Rectangle(20, 20, 200, 200);
    clip.setArcHeight(15);
    clip.setArcWidth(15);

    Shape shape = Shape.subtract(rect, clip);

    shape.setFill(Color.GRAY);
    group.getChildren().add(shape);
    Scene scene = new Scene(group);
    scene.setFill(Color.TRANSPARENT);
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.setScene(scene);
    stage.show();
}

任何链接或帮助将不胜感激。

最佳答案

如果您通过 Shape.subtract(...) 创建一个 Shape,则之后您没有任何机制可以更改它的属性(即更改用于创建它的形状的边界)。您必须从其父级中删除形状,重新计算矩形和剪辑,重新计算形状,然后将新形状添加回场景中。

这里最好使用Path,这样您就可以操纵坐标,而无需每次都创建新形状。以一种方式(例如顺时针)围绕外部(填充部分)移动,然后以另一种方式(逆时针)围绕内部(透明部分)移动。所得形状将与从外部减去内部部分相同。初始设置可能需要更多的代码,但您可以根据需要操纵坐标。

我不确定您到底在寻找什么功能,但以下功能允许您通过单击并拖动内部部分来拖动内部部分,并允许您通过单击并拖动外部部分来移动整个窗口。这应该足以让您弄清楚自己需要什么。我没有在示例中包含漂亮的圆角,但您可以相当轻松地使用 ArcTo 路径元素实现这些圆角。

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ObservableDoubleValue;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class TransparentRectangle extends Application {


    @Override
    public void start(Stage stage) {

        Pane root = new Pane();

        PathElement start = new MoveTo(0, 0);
        PathElement outerTopRight = createBoundLineTo(root.widthProperty(), 0);
        PathElement outerBottomRight = createBoundLineTo(root.widthProperty(), root.heightProperty());
        PathElement outerBottomLeft = createBoundLineTo(0, root.heightProperty());
        PathElement outerTopLeft = new LineTo(0, 0);

        DoubleProperty innerLeft = new SimpleDoubleProperty(20);
        DoubleProperty innerTop = new SimpleDoubleProperty(20);
        DoubleBinding innerRight = innerLeft.add(180);
        DoubleBinding innerBottom = innerTop.add(180);

        PathElement innerTopLeft = createBoundLineTo(innerLeft, innerTop);
        PathElement innerTopRight = createBoundLineTo(innerRight, innerTop);
        PathElement innerBottomRight = createBoundLineTo(innerRight, innerBottom);
        PathElement innerBottomLeft = createBoundLineTo(innerLeft, innerBottom);

        Path path = new Path(
                start, outerTopRight,
                outerBottomRight, outerBottomLeft,
                outerTopLeft, 
                innerTopLeft, innerBottomLeft, 
                innerBottomRight, innerTopRight,
                innerTopLeft, new ClosePath()
        );


        path.setFill(Color.GRAY);
        path.setStroke(Color.TRANSPARENT);
        root.getChildren().add(path);

        class Wrapper<T> { T value ; }
        Wrapper<Point2D> mouseLocation = new Wrapper<>();

        // Drag on gray portion of path - move entire window:
        path.setOnDragDetected(event -> {
            mouseLocation.value = new Point2D(event.getScreenX(), event.getScreenY());
        });
        path.setOnMouseDragged(event -> {
            if (mouseLocation.value != null) {
                stage.setX(stage.getX() + event.getScreenX() - mouseLocation.value.getX());
                stage.setY(stage.getY() + event.getScreenY() - mouseLocation.value.getY());
                mouseLocation.value = new Point2D(event.getScreenX(), event.getScreenY());
            }
        });
        path.setOnMouseReleased(event -> mouseLocation.value = null);


        // Drag on scene (i.e not on path, i.e. on transparent part) - move transparent part
        root.setOnDragDetected(event -> {
            mouseLocation.value = new Point2D(event.getScreenX(), event.getScreenY());
        });
        root.setOnMouseDragged(event -> {
            if (mouseLocation.value != null) {
                innerLeft.set(innerLeft.get() + event.getScreenX() - mouseLocation.value.getX());
                innerTop.set(innerTop.get() + event.getScreenY() - mouseLocation.value.getY());
                mouseLocation.value = new Point2D(event.getScreenX(), event.getScreenY());
            }
        });
        root.setOnMouseReleased(event -> mouseLocation.value = null);

        // No close button on a transparent window, so exit on double click:
        root.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2) Platform.exit();
            event.consume();
        });

        Scene scene = new Scene(root, 800, 600);

        scene.setFill(Color.TRANSPARENT);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setScene(scene);
        stage.show();
    }

    private PathElement createBoundLineTo(ObservableDoubleValue x, ObservableDoubleValue y) {
        LineTo lineTo = new LineTo();
        lineTo.xProperty().bind(x);
        lineTo.yProperty().bind(y);
        return lineTo ;
    }

    private PathElement createBoundLineTo(double fixedX, ObservableDoubleValue y) {
        LineTo lineTo = new LineTo();
        lineTo.setX(fixedX);
        lineTo.yProperty().bind(y);
        return lineTo ;
    }

    private PathElement createBoundLineTo(ObservableDoubleValue x, double fixedY) {
        LineTo lineTo = new LineTo();
        lineTo.setY(fixedY);
        lineTo.xProperty().bind(x);
        return lineTo ;
    }

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

关于java - 调整减法形状的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26254354/

相关文章:

JavaFX:单个图像中的多个快照

java - 如何配置 Inno Setup 以检查 Visual C++ Redistributable Packages

java - 在设置了*中断状态*的情况下调用 Thread.sleep()?

java - 这个关键字及其工作原理

java - 我的 fxgl 遇到非法状态异常 : EntityFactory was not set!

html - 倾斜或扭曲的边框形状

Android创建半可调整大小的框

android - 在 Android 中使用 XML 形状设置绘制矩形

java - 没有这样的列 _id Android、Java、SQL

java - Lucene 4.6 中的 ShingleFilter 将单词添加到二元组中