2015-08-25 3 views
1

В моей программе я хочу, чтобы объекты отображались, что они перемещаются из одного места в другое. Я использовал TranslateTransition. Чтобы он работал, мне нужно дать ему исходное местоположение, в моем случае, расстояние до исходного узла.Поиск расстояния между двумя узлами для TranslateTransition

enter image description here

Проблема, это два узла находятся в отдельных контейнерах, так просто с помощью layoutX и layoutY в расчет не будет работать.

В моем коде ниже я использовал метод localToScene для преобразования координат относительно локального узла в сцену. Затем я сделал небольшое вычитание, чтобы получить расстояние между двумя узлами относительно движущегося узла.

import com.neonorb.commons.log.Log; 
import javafx.application.Platform; 
import javafx.beans.Observable; 
import javafx.beans.binding.Bindings; 
import javafx.beans.binding.DoubleBinding; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.scene.Node; 
import javafx.scene.Parent; 
import sun.reflect.generics.reflectiveObjects.LazyReflectiveObjectGenerator; 

import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.Callable; 
import java.util.stream.Collectors; 

/** 
* Created by chris on 8/23/15. 
*/ 
public class TranslateUtils { 
    public static DoubleProperty getTranslateX(Node translatingNode, Node otherNode) { 
     DoubleProperty ret = new SimpleDoubleProperty(); 
     Platform.runLater(() -> { 
      List<Observable> dependencies = getAllParents(translatingNode).stream().map(Node::layoutXProperty).collect(Collectors.toList()); 
      dependencies.addAll(getAllParents(otherNode).stream().map(Node::layoutXProperty).collect(Collectors.toList())); 
      ret.bind(Bindings.createDoubleBinding(new Callable<Double>() { 
       @Override 
       public Double call() throws Exception { 
        Log.debug("recalculating x"); 
        return otherNode.localToScene(otherNode.getBoundsInLocal()).getMinX() - translatingNode.localToScene(translatingNode.getBoundsInLocal()).getMinX(); 
       } 
      }, dependencies.toArray(new Observable[dependencies.size()]))); 
     }); 
     return ret; 
    } 

    public static DoubleProperty getTranslateY(Node translatingNode, Node otherNode) { 
     DoubleProperty ret = new SimpleDoubleProperty(); 
     Platform.runLater(() -> { 
      List<Observable> dependencies = getAllParents(translatingNode).stream().map(Node::layoutXProperty).collect(Collectors.toList()); 
      dependencies.addAll(getAllParents(otherNode).stream().map(Node::layoutXProperty).collect(Collectors.toList())); 
      ret.bind(Bindings.createDoubleBinding(new Callable<Double>() { 
       @Override 
       public Double call() throws Exception { 
        Log.debug("recalculating y"); 
        return otherNode.localToScene(otherNode.getBoundsInLocal()).getMinY() - translatingNode.localToScene(translatingNode.getBoundsInLocal()).getMinY(); 
       } 
      }, dependencies.toArray(new Observable[dependencies.size()]))); 
     }); 
     return ret; 
    } 

    private static List<Parent> getAllParents(Node node) { 
     List<Parent> parents = new ArrayList<Parent>(); 
     Parent parent = node.getParent(); 
     if (parent != null) { 
      parents.addAll(getAllParents(parent)); 
      parents.add(parent); 
     } 
     return parents; 
    } 
} 

Вы можете проверить код с этим:

import javafx.animation.TranslateTransition; 
import javafx.application.Application; 
import javafx.application.Platform; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 
import javafx.util.Duration; 
import org.controlsfx.tools.Borders; 

import java.io.IOException; 

/** 
* Created by chris on 7/20/15. 
*/ 
public class Test extends Application { 
    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws IOException { 
     BorderPane borderPane = new BorderPane(); 
     Label translatingNode = new Label("translating node"); 
     HBox translatingHBox = new HBox(translatingNode); 
     translatingHBox.setAlignment(Pos.CENTER); 
     borderPane.setTop(translatingHBox); 
     Label referenceNode = new Label("reference node"); 
     HBox referenceHBox = new HBox(referenceNode); 
     referenceHBox.setAlignment(Pos.CENTER_RIGHT); 
     borderPane.setBottom(referenceHBox); 
     TranslateTransition translateTransition = new TranslateTransition(Duration.seconds(3), translatingNode); 
     translateTransition.fromXProperty().bind(TranslateUtils.getTranslateX(translatingNode, referenceNode)); 
     translateTransition.fromYProperty().bind(TranslateUtils.getTranslateY(translatingNode, referenceNode)); 
     translateTransition.setToX(0); 
     translateTransition.setToY(0); 
     Button playButton = new Button("play"); 
     playButton.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent actionEvent) { 
       translateTransition.play(); 
      } 
     }); 
     borderPane.setCenter(playButton); 
     primaryStage.setScene(new Scene(borderPane)); 
     primaryStage.show(); 
    } 
} 

Вы можете успешно играть анимации в первый раз, но попробуйте изменить размер окна. Местоположение переводов не обновляется.

ответ

0

Я закончил с использованием собственных методов, чтобы найти глобальное местоположение:

private static double getGlobalX(Node node) { 
    if (node == null) { 
     return 0.0; 
    } 
    double parentGlobalX = getGlobalX(node.getParent()); 
    return node.getLayoutX() - parentGlobalX; 
} 

private static double getGlobalY(Node node) { 
    if (node == null) { 
     return 0.0; 
    } 
    double parentGlobalY = getGlobalY(node.getParent()); 
    return parentGlobalY - node.getLayoutY(); 
} 
1

Вы не указали layoutXProperty самого translatingNode. Чтобы исправить демо, просто включить сам узел в списке своих родителей:

private static List<Node> getAllParents(Node node) { 
    List<Node> parents = new ArrayList<Node>(); 
    if (node != null) { 
     parents.addAll(getAllParents(node.getParent())); 
     parents.add(node); 
    } 
    return parents; 
} 
+0

Это был вопрос, но в моем случае это не проблема. –

+0

Я использую собственные методы, чтобы найти местоположение вместо встроенных. Возможно, это устранило проблему, но я сомневаюсь. Не собираюсь тестировать это :) –

Смежные вопросы