2017-05-22 3 views
0

나는 PaneVBoxLine을 포함하고 있습니다. (VBox 내부의 "앵커"에 Line의 끝점을 바인딩하고 싶습니다. (기본적으로 Node의 위치에 바인딩하려면 임의로 VBox에 중첩되어 있습니다.) 그러나 어떤 값이 Node의 위치는 상단을 기준으로 Pane입니다. 나는 레이아웃 속성을 시도하고 속성을 번역 할뿐만 아니라 부모와 지역 경계의 경계를 번역했고 그 중 아무 것도 작동하지 않는 것 같습니다. 내가 뭘 놓치고 있니?JavaFX : 중첩 위치에 바인딩

(필요한 경우 내가 코드 샘플을 제공 할 수 있습니다,하지만 난 그것이 내가이 일을 얻을 수 없기 때문에 더 나은 내 문제를 설명 할 수 있다고 생각하지 않습니다.)

편집 : 나는 VBox을 언급하는 것을 잊었다 창 주위를 자유롭게 이동할 수 있기 때문에 선을 묶어야합니다.

편집 : 내 진행 상황을 보여주는 소스가 있습니다. 나는 정확한 위치를 얻을 수 있지만, 그것은 어떤 Node node을 감안할 때

public class Graph extends Application { 
    private double startX; 
    private double startY; 

    private ObjectBinding<Bounds> bounds; 
    private DoubleBinding tx; 
    private DoubleBinding ty; 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Pane pane = new Pane(); 
     Circle target = new Circle(5, Color.RED); 
     VBox node = wrap(target); 
     Line connector = new Line(); 
     bounds = Bindings.createObjectBinding(() -> { 
        Bounds nodeLocal = target.getBoundsInLocal(); 
        Bounds nodeScene = target.localToScene(nodeLocal); 
        Bounds nodePane = pane.sceneToLocal(nodeScene); 
        return nodePane; 
       }, 
       target.boundsInLocalProperty(), 
       target.localToSceneTransformProperty(), 
       pane.localToSceneTransformProperty() 
     ); 
     connector.setStartX(0); 
     connector.setStartY(0); 
     tx = Bindings.createDoubleBinding(() -> bounds.get().getMinX(), bounds); 
     ty = Bindings.createDoubleBinding(() -> bounds.get().getMinY(), bounds); 
     connector.endXProperty().bind(tx); 
     connector.endYProperty().bind(ty); 
     connector.setStroke(Color.BLACK); 
     pane.getChildren().add(node); 
     pane.getChildren().add(connector); 
     node.relocate(100, 100); 
     primaryStage.setScene(new Scene(pane, 300, 300)); 
     primaryStage.show(); 
    } 

    private VBox wrap(Circle target) { 
     VBox node = new VBox(new Label("Node"), new StackPane(new Rectangle(50, 50, Color.GRAY), target)); 
     node.setOnMousePressed(event -> { 
      Node source = (Node) event.getSource(); 
      startX = source.getBoundsInParent().getMinX() - event.getScreenX(); 
      startY = source.getBoundsInParent().getMinY() - event.getScreenY(); 
     }); 
     node.setOnMouseDragged(event -> { 
      Node source = (Node) event.getSource(); 
      double offsetX = event.getScreenX() + startX; 
      double offsetY = event.getScreenY() + startY; 
      source.relocate(offsetX, offsetY); 
     }); 
     return node; 
    } 
} 

답변

1

바인딩 아니에요 Pane pane, 기본적인 아이디어는 다음

ObjectBinding<Bounds> boundsInPaneBinding = Bindings.createObjectBinding(() -> { 
     Bounds nodeLocal = node.getBoundsInLocal(); 
     Bounds nodeScene = node.localToScene(nodeLocal); 
     Bounds nodePane = pane.sceneToLocal(nodeScene); 
     return nodePane ; 
    }, node.boundsInLocalProperty(), node.localToSceneTransformProperty(), 
     pane.localToSceneTransformProperty()); 

boundsInPaneBinding을하는 것입니다 (의미가 부모 또는 간접적 인 조상을 가지고) 의 좌표계에 항상 Node의 경계를 포함하는 ObservableValue<Bounds>입니다. 그래서 당신은 다음

line.startXProperty().bind(Bindings.createDoubleBinding(
    () -> boundsInPaneBinding.get().getMinX(), 
    boundsInPaneBinding)); 

여기에 까다로운 부분과 같은 일을 할 수는 바인딩이 조기에 수집 된 쓰레기를하지 않도록하고있다. (토론에 대한 here를 참조하십시오.) 먼저, 바인딩에 대한 참조를 유지해야합니다 다음

private ObjectBinding<Bounds> boundsInPaneBinding ; 

와 (이유 나는 확실히 알아낼 수 없습니다)을, 바인딩은 실제로 직접 바인딩 속성을 평가해야 :

boundsInPaneBinding = Bindings.createObjectBinding(() -> { 
     Bounds nodeLocal = node.getBoundsInLocal(); 
     // note how this actually gets the value of localToSceneTransformProperty(): 
     Bounds nodeScene = node.getLocalToSceneTransform().apply(nodeLocal); 
     Bounds nodePane = pane.sceneToLocal(nodeScene); 
     return nodePane ; 
    }, node.boundsInLocalProperty(), node.localToSceneTransformProperty(), 
     pane.localToSceneTransformProperty()); 
+0

거의 내가 원하는대로합니다. 선은 바른 장소에서 끝나지 만 바운더리에 머 무르지 않습니다. 문제가 무엇인지 알 것 같아. –

+0

신경 쓰지 마라. 그것은 작동하지 않았다. 나는'VBox' 자체가 아닌'VBox'에서'Node'의 위치에 바인딩하려고합니다. –

+1

@ RuckusT-Boom 똑같은 기술을 사용할 수 있습니다. 위의 코드에서 vbox를 관심 노드로 바꿉니다. (답변을 반영하여 수정했습니다.) 바운드 상태가 아닌 문제는 [this one] 일 가능성이 있습니다 (https://stackoverflow.com/questions/23785816/javafx-beans-binding-suddenly-stops-working). 당신은 바인딩에 대한 참조를 유지합니다. –