我想调整下面创建的形状的大小。但无法得到它。 该项目是创建一个透明矩形,仅显示桌面的一部分,并隐藏其余部分。透明区域是减法的结果,我需要让用户调整大小。
我尝试了几种方法,例如改编: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();
}
任何链接或帮助都将不胜感激。
答案 0 :(得分:1)
如果您通过Shape
创建Shape.subtract(...)
,那么之后您就没有任何机制可以更改它的属性(从更改用于的形状的界限的意义上来说)创造它)。您必须从其父级中删除形状,重新计算矩形和剪辑,重新计算形状,然后将新形状添加回场景。
在这里使用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);
}
}