В моей программе я хочу, чтобы объекты отображались, что они перемещаются из одного места в другое. Я использовал TranslateTransition
. Чтобы он работал, мне нужно дать ему исходное местоположение, в моем случае, расстояние до исходного узла.Поиск расстояния между двумя узлами для TranslateTransition
Проблема, это два узла находятся в отдельных контейнерах, так просто с помощью 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();
}
}
Вы можете успешно играть анимации в первый раз, но попробуйте изменить размер окна. Местоположение переводов не обновляется.
Это был вопрос, но в моем случае это не проблема. –
Я использую собственные методы, чтобы найти местоположение вместо встроенных. Возможно, это устранило проблему, но я сомневаюсь. Не собираюсь тестировать это :) –