Animation Javafx中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.

我试图模拟排序算法。所以我需要移动两个数字来表示它们之间的交换。但大多数时候,它开始从一个错误的地方移动到另一个错误的地方。以下是我使用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.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();
}