2014-10-08 7 views
1

아래에 만든 모양의 크기를 조정하고 싶습니다. 그러나 그것을 얻을 수 없다. 프로젝트는 바탕 화면의 일부만 표시하고 나머지는 숨기위한 투명 사각형을 만드는 것입니다. 투명 영역은 빼기 결과이며 사용자가 크기를 조정할 수 있어야합니다. 빼기 모양의 크기 조정

나는 이와에서 적응 등 여러 가지 방법으로, tryed : 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(); 
} 

모든 링크 나 도움을 주시면 감사하겠습니다 :

여기 내 코드입니다.

답변

1

Shape.subtract(...)으로 Shape을 만들면 이후에 속성을 만들 수있는 메커니즘이 없습니다 (이 특성을 만드는 데 사용 된 모양의 경계를 변경한다는 의미에서). 셰이프를 부모에서 제거하고 rect 및 클립을 다시 계산하고 셰이프를 다시 계산하여 새 셰이프를 다시 장면에 추가해야합니다.

여기에 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); 
    } 
} 
+0

멋진 접근 방식, 많은 감사합니다. 지금 코드 할 수 있지만 두 가지 포인트가 있습니다 : 1. 투명 영역의 크기를 조정하는 방법 2. 투명 영역을 끌 수있는 영역을 얻는 것은 어렵습니다. 나는 그것을 어떻게 더 크게 만들 수 있을까? –

+0

내부 영역의 크기를 조정할 수있게하려면'innerRight'와'innerBottom'에 대한 일반 속성을 만듭니다 (innerLeft와 innerTop에 바인드하지 마십시오). 그런 다음 독립적으로 조작하여 크기를 변경할 수 있습니다. 두 번째 질문은 이해할 수 없지만이 예제에서는 전체 영역이 장면의 크기 ('new Scene (root, 800, 600))로 정의됩니다. –

+0

첫 번째로 시도해 보겠습니다. 두 번째로 시도해 보겠습니다. 내부 투명도를 파란색으로 변경하여 작동 방식을 확인했습니다. 투명하게, inne 영역을 드래그하는 것은 어렵습니다. –