Animation Javafx中TranslateTransition的起始和结束错误
我试图模拟排序算法。所以我需要移动两个数字来表示它们之间的交换。但大多数时候,它开始从一个错误的地方移动到另一个错误的地方。以下是我使用TranslateTransition的代码:Animation Javafx中TranslateTransition的起始和结束错误,animation,javafx,transition,Animation,Javafx,Transition,我试图模拟排序算法。所以我需要移动两个数字来表示它们之间的交换。但大多数时候,它开始从一个错误的地方移动到另一个错误的地方。以下是我使用TranslateTransition的代码: public static void showSwap(Text t1, Text t2) { double x1, x2, z; x1=t1.getX(); x2=t2.getX(); z=x2-x1; pt = new PauseTransition(Duration.
public static void showSwap(Text t1, Text t2)
{
double x1, x2, z;
x1=t1.getX();
x2=t2.getX();
z=x2-x1;
pt = new PauseTransition(Duration.millis(1000));
t1up = new TranslateTransition(Duration.millis(900), t1);
t1up.setFromY(0);
t1up.setToY(-55);
t1up.setCycleCount(1);
t1right = new TranslateTransition(Duration.millis(900), t1);
t1right.setFromX(0);
t1right.setToX(z);
t1right.setCycleCount(1);
t1down = new TranslateTransition(Duration.millis(900), t1);
t1down.setFromY(-55);
t1down.setToY(0);
t1down.setCycleCount(1);
t1.toFront();
sequentialTransition1.getChildren().addAll(t1up,t1right,t1down,pt);
t2down = new TranslateTransition(Duration.millis(900), t2);
t2down.setFromY(0);
t2down.setToY(55);
t2down.setCycleCount(1);
t2left = new TranslateTransition(Duration.millis(900), t2);
t2left.setFromX(0);
t2left.setToX(-z);
t2left.setCycleCount(1);
t2up = new TranslateTransition(Duration.millis(900), t2);
t2up.setFromY(55);
t2up.setToY(0);
t2up.setCycleCount(1);
t2.toFront();
sequentialTransition2.getChildren().addAll(t2down,t2left,t2up,pt);
}
我也试过这个部分,但它得到了NullPointerException
public static void showSwap2(Text t1, Text t2)
{
double x1, x2, y;
x1=t1.getX();
x2=t2.getX();
y=t1.getY();
MoveTo start1 = new MoveTo( x1, y );
ArcTo end1 = new ArcTo();
end1.setX(x2);
end1.setY(y);
end1.setRadiusX(100);
end1.setRadiusY(100);
Path path1 = new Path();
path1.getElements().addAll(start1, end1);
PathTransition transition1 = new PathTransition();
transition1.setDuration(Duration.millis(900));
transition1.setPath(path1);
sequentialTransition1.getChildren().addAll(transition1);
MoveTo start2 = new MoveTo( x1, y );
ArcTo end2 = new ArcTo();
end2.setX(x2);
end2.setY(y);
end2.setRadiusX(100);
end2.setRadiusY(100);
Path path2 = new Path();
path2.getElements().addAll( start2, end2 );
PathTransition transition2 = new PathTransition();
transition2.setDuration(Duration.millis(900));
transition2.setPath(path2);
sequentialTransition2.getChildren().addAll(transition2);
}
下面是我调用showSwap()方法的部分:
公共最终类BubbleSort扩展模拟器控制器实现可初始化
{
公共BubbleSort(窗格根,整数总数)
{
int i,j,温度;
对于(i=totalNumbers-2;i>=0;i--)
{
对于(j=0;j个数字。获取(j+1))
{
showSwap(textNumbers.get(j),textNumbers.get(j+1));
温度=数字。获取(j);
number.set(j,number.get(j+1));
编号。设置(j+1,温度);
}
}
}
}
}
这是控制器类:
public class SimulatorController implements Initializable
{
@FXML protected Canvas img ;
@FXML protected Button prev;
@FXML protected Button next;
@FXML protected BorderPane root;
protected static SequentialTransition sequentialTransition1;
protected static SequentialTransition sequentialTransition2;
protected int totalNumbers=5;
protected static boolean nextMove=false;
protected static boolean prevMove=false;
protected static boolean simulateAutomatically=false;
protected static ArrayList<Rectangle> rect = new ArrayList<Rectangle>();
protected static ArrayList<Text> textNumbers=new ArrayList<Text>();
protected ArrayList<Text> textIndex=new ArrayList<Text>();
protected static ArrayList<Integer> numbers=new ArrayList<Integer>();
protected ArrayList<Integer> index=new ArrayList<Integer>();
protected static TranslateTransition t1right;
protected static TranslateTransition t1up;
protected static TranslateTransition t1down;
protected static TranslateTransition t2left;
protected static TranslateTransition t2down;
protected static TranslateTransition t2up;
protected static PauseTransition pt;
@Override
public void initialize(URL location, ResourceBundle resources)
{
drawArrayAndNumbers();
sequentialTransition1 = new SequentialTransition(); sequentialTransition2 = new SequentialTransition(); sequentialTransition1.setCycleCount(1); sequentialTransition2.setCycleCount(1);
new BubbleSort(root,totalNumbers);
sequentialTransition1.play();
sequentialTransition2.play();
root.setOnMouseClicked(new EventHandler<MouseEvent>()
{
@Override public void handle(MouseEvent mouseEvent)
{
System.out.println(("X="+mouseEvent.getScreenX()+" || Y="+mouseEvent.getScreenY()));
}
});
}
void drawArrayAndNumbers()
{
int i, x=50, y=250, rectSizeX=70, rectsizeY=50;
for(i=0;i<totalNumbers;i++,x+=rectSizeX+35)
{
rect.add(i, new Rectangle(x, y, rectSizeX, rectsizeY));
rect.get(i).setArcHeight(10);
rect.get(i).setArcWidth(10);
rect.get(i).setFill(Color.SKYBLUE);
numbers.add(i,100+(int)(Math.random()*899));
index.add(i);
textNumbers.add(i, new Text (x+15, y+30, Integer.toString(numbers.get(i))));
textNumbers.get(i).setFill(Color.BLACK);
textNumbers.get(i).setFont(new Font(25));
textIndex.add(i, new Text (x+30, y+rectsizeY+15, Integer.toString(i)));
textIndex.get(i).setFill(Color.BLACK);
textIndex.get(i).setFont(new Font(15));
root.getChildren().addAll(rect.get(i),textNumbers.get(i),textIndex.get(i));
}
}
}
公共类模拟器控制器实现可初始化
{
@FXML保护画布img;
@FXML保护按钮prev;
@FXML保护按钮下一步;
@FXML保护的边界窗格根;
受保护的静态顺序转换顺序转换1;
受保护的静态顺序转换顺序转换2;
受保护整数总数=5;
受保护的静态布尔值nextMove=false;
受保护的静态布尔值prevMove=false;
受保护的静态布尔模拟自动=false;
受保护的静态ArrayList rect=新ArrayList();
受保护的静态ArrayList textNumbers=新ArrayList();
受保护的ArrayList textIndex=新ArrayList();
受保护的静态ArrayList编号=新ArrayList();
受保护的ArrayList索引=新的ArrayList();
受保护的静态翻译权;
受保护的静态转换t1up;
受保护的静态平移t1down;
受保护的静态平移t2left;
受保护的静态平移t2down;
受保护的静态转换t2up;
保护静态暂停转换pt;
@凌驾
公共void初始化(URL位置、ResourceBundle资源)
{
DrawarrayandNumber();
sequentialTransition1=新SequentialTransition();sequentialTransition2=新SequentialTransition();sequentialTransition1.setCycleCount(1);sequentialTransition2.setCycleCount(1);
新BubbleSort(根,总数);
顺序转换1.play();
顺序转换2.play();
setOnMouseClicked(新的EventHandler()
{
@重写公共无效句柄(MouseEvent MouseEvent)
{
System.out.println((((“X=“+mouseEvent.getScreenX()+”|124; Y=“+mouseEvent.getScreenY()));
}
});
}
无效DrawarrayandNumber()
{
int i,x=50,y=250,rectSizeX=70,rectsizeY=50;
对于(i=0;i您使用Text
的x
和y
位置。但是,这不是所有节点
都通用的属性。设置动画的属性是translateX
和translateY
属性。因此
x1=t1.getX();
x2=t2.getX();
z=x2-x1;
结果是z
是原点x坐标之间的差值,而不是上一次转换后位置之间的差值。此外,在动画完成之前调用此函数,因此即使修复了前面提到的问题,也会使用当前位置进行计算,而不是位置在上一个动画之后对节点进行初始化
要解决此问题,请保存初始位置并使用translate
属性定位节点:
public class SwapAnimationQueue<T extends Node> {
private final SequentialTransition transitionUpper;
private final SequentialTransition transitionLower;
private final T[] nodes;
private final double[] positionX;
public SwapAnimationQueue(T... nodes) {
this.transitionLower = new SequentialTransition();
this.transitionUpper = new SequentialTransition();
this.nodes = nodes.clone();
positionX = new double[nodes.length];
for (int i = 0; i < nodes.length; i++) {
positionX[i] = nodes[i].getTranslateX();
}
}
public void play() {
this.transitionLower.play();
this.transitionUpper.play();
}
public void swap(int index1, int index2) {
if (index1 == index2) {
return;
}
T temp;
createTransition(transitionUpper, index1, index2, temp = nodes[index1], true);
createTransition(transitionLower, index2, index1, nodes[index2], false);
nodes[index1] = nodes[index2];
nodes[index2] = temp;
}
private void createTransition(SequentialTransition transition, int startPosition, int endPosition, Node node, boolean upper) {
double dy = upper ? -55 : 55;
TranslateTransition vertical1 = new TranslateTransition(Duration.millis(900), node);
vertical1.setByY(dy);
TranslateTransition horizontal = new TranslateTransition(Duration.millis(900), node);
horizontal.setByX(positionX[endPosition] - positionX[startPosition]);
TranslateTransition vertical2 = new TranslateTransition(Duration.millis(900), node);
vertical2.setByY(-dy);
transition.getChildren().addAll(vertical1, horizontal, vertical2);
}
}
用法
公共作废开始(阶段primaryStage){
字符串[]text={“3”、“2”、“1”};
Text[]textNodes=新文本[Text.length];
for(int i=0;i
我尝试了你的第一个版本,在一个可执行示例中加入了我所能做到的最小数量,效果很好。因此,你的错误在代码的其他部分。请在你的问题中包含一个说明问题的例子(这样你就可以保证你的问题包括你做错的任何事情)。不是x
和y
属性,而是translateX
和translateY
属性都是动画。这会打乱您对以前移动的节点的计算。@James\u D第一个版本在这里大部分时间都不起作用。我试图添加更多内容来澄清。我已经在google drive上上传了完整的程序包我也提供了那个链接。如果我需要更具体一些,请告诉我。@fabian我不知道我必须做什么。可以指定一个新的坐标来移动吗?比如,这里我需要将text1移动到text2的X轴位置,反之亦然。非常感谢fabian先生。最后我成功地实现了您给定的代码.现在它工作得很好,这是我需要的。
public class SwapAnimationQueue<T extends Node> {
private final SequentialTransition transitionUpper;
private final SequentialTransition transitionLower;
private final T[] nodes;
private final double[] positionX;
public SwapAnimationQueue(T... nodes) {
this.transitionLower = new SequentialTransition();
this.transitionUpper = new SequentialTransition();
this.nodes = nodes.clone();
positionX = new double[nodes.length];
for (int i = 0; i < nodes.length; i++) {
positionX[i] = nodes[i].getTranslateX();
}
}
public void play() {
this.transitionLower.play();
this.transitionUpper.play();
}
public void swap(int index1, int index2) {
if (index1 == index2) {
return;
}
T temp;
createTransition(transitionUpper, index1, index2, temp = nodes[index1], true);
createTransition(transitionLower, index2, index1, nodes[index2], false);
nodes[index1] = nodes[index2];
nodes[index2] = temp;
}
private void createTransition(SequentialTransition transition, int startPosition, int endPosition, Node node, boolean upper) {
double dy = upper ? -55 : 55;
TranslateTransition vertical1 = new TranslateTransition(Duration.millis(900), node);
vertical1.setByY(dy);
TranslateTransition horizontal = new TranslateTransition(Duration.millis(900), node);
horizontal.setByX(positionX[endPosition] - positionX[startPosition]);
TranslateTransition vertical2 = new TranslateTransition(Duration.millis(900), node);
vertical2.setByY(-dy);
transition.getChildren().addAll(vertical1, horizontal, vertical2);
}
}
private void createTransition(SequentialTransition transition, int startPosition, int endPosition, Node node, boolean upper) {
double x1 = positionX[startPosition];
double x2 = positionX[endPosition];
MoveTo move = new MoveTo(x1, node.getTranslateY());
double radius = Math.abs(x2-x1) / 2;
ArcTo arc = new ArcTo(radius, 20, 0, x2-x1, 0, upper, true);
arc.setAbsolute(false);
transition.getChildren().add(new PathTransition(Duration.millis(900), new Path(move, arc), node));
}
public void start(Stage primaryStage) {
String[] text = {"3", "2", "1"};
Text[] textNodes = new Text[text.length];
for (int i = 0; i < text.length; i++) {
Text t = new Text(text[i]);
t.setTranslateX(20 + i * 50);
t.setTranslateY(100);
textNodes[i] = t;
}
SwapAnimationQueue swapper = new SwapAnimationQueue(textNodes);
Pane p = new Pane();
p.getChildren().addAll(textNodes);
swapper.swap(0, 1);
swapper.swap(1, 2);
swapper.swap(0, 1);
Scene scene = new Scene(p, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
swapper.play();
}