Animation 转换控件时发生JavaFX动画错误

Animation 转换控件时发生JavaFX动画错误,animation,javafx-2,Animation,Javafx 2,我正在尝试使用PathTransition转换JavaFX控件。在执行过程中,控件不稳定地移动(我使它在矩形中工作) 附着的样本尝试根据其他两个标签的位置将标签从一个位置移动到另一个位置。标签立即跳到其假定起点下方的一个点,然后过渡到其预期目标位置下方的另一个点 调试信息指示标签从(50,50)开始,偏移量为(0,0),目标是新位置(200,50)。当动画完成时,我相信它应该位于偏移量为(150,0)的位置(50,50);事实上,它的位置为(50,50),偏移量为(148,38.5) 我做错了什

我正在尝试使用PathTransition转换JavaFX控件。在执行过程中,控件不稳定地移动(我使它在矩形中工作)

附着的样本尝试根据其他两个标签的位置将标签从一个位置移动到另一个位置。标签立即跳到其假定起点下方的一个点,然后过渡到其预期目标位置下方的另一个点

调试信息指示标签从(50,50)开始,偏移量为(0,0),目标是新位置(200,50)。当动画完成时,我相信它应该位于偏移量为(150,0)的位置(50,50);事实上,它的位置为(50,50),偏移量为(148,38.5)

我做错了什么

谢谢你的帮助

package fxsort;

import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.scene.shape.ArcTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.text.Font;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Test4
    extends Application
{
    private final Label   statLabel1        =
        getLabel( "Jehosaphat", 50, 50, Color.gray( .85 ) );
    private final Label   statLabel2        =
        getLabel( "Jehosaphat", 200, 50, Color.gray( .85 ) );
    private final Label   periLabel    =
        getLabel( "Jehosaphat", 50, 50, Color.RED );

public static void main(String[] args)
{
    launch( args );
}

@Override
public void start(Stage stage) throws Exception
{
    Button  start               = new Button( "Start" );

    start.relocate( 250, 125 );
    start.setOnAction(
        new EventHandler<ActionEvent>()
        {
            @Override
            public void handle( ActionEvent evt )
            {
                PathTransition  transition  = getTransition();
                transition.play();
            }
        }
    );

    Group   root    =
        new Group( statLabel1, statLabel2, periLabel, start );
    stage.setScene( new Scene( root, 350, 200 ) ) ;
    stage.show();
}

private Label
getLabel( String text, double xco, double yco, Color color )
{
    Label   label   = new Label( text );
    label.relocate( xco, yco );
    label.setTextFill( color );
    label.setFont( Font.font( "Arial", 20 ) );

    return label;
}
private PathTransition
getTransition()
{
    Label       from        = statLabel1;
    Label       too         = statLabel2;
    Duration    duration    = Duration.millis( 3000 );
    double      startX      = from.getLayoutX();// + 30;
    double      startY      = from.getLayoutY();// + 30;
    System.out.println( "From Layout: " + startX + ", " + startY );
    System.out.println( "From Offset: " + from.getTranslateX()
                         + ", " + from.getTranslateX() );

    double      endX        = too.getLayoutX();// + 30;
    double      endY        = too.getLayoutY();// + 30;
    System.out.println( "To Layout: " + endX + ", " + endY );
    System.out.println( "To Offset: " + too.getTranslateX()
                         + ", " + too.getTranslateX() );

    MoveTo      start       = new MoveTo( startX, startY );
    System.out.println( "MoveTo: " + start.getX() + ", " + start.getY() );

    ArcTo       end     = new ArcTo();
    end.setX( endX );
    end.setY( endY );
    end.setRadiusX( 100 );
    end.setRadiusY( 100 );
    System.out.println( "ArcTo: " + end.getX() + ", " + end.getY() );

    System.out.println( "**********" );

    Path    path    = new Path();
    path.getElements().addAll( start, end );

    PathTransition  transition  = new PathTransition();
    transition.setDuration( duration );
    transition.setPath( path );
    transition.setNode( periLabel );

    transition.setOnFinished(
        new EventHandler<ActionEvent>()
        {
            public void handle( ActionEvent evt )
            {
                System.out.println( "Landed: " + periLabel.getLayoutX()
                                    + ", " + periLabel.getLayoutY() );
                System.out.println( "Offset: " + periLabel.getTranslateX()
                                    + ", " + periLabel.getTranslateY() );
            }
        }
    );

    return transition;
}
}
package-fxsort;
导入javafx.animation.PathTransition;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.ArcTo;
导入javafx.scene.shape.MoveTo;
导入javafx.scene.shape.Path;
导入javafx.scene.text.Font;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类Test4
扩展应用程序
{
专用最终标签statLabel1=
getLabel(“约萨法”,50,50,颜色为灰色(.85));
专用最终标签statLabel2=
getLabel(“约萨法”,200,50,颜色为灰色(.85));
专用最终标签Periabel=
getLabel(“约萨法”,50,50,颜色为红色);
公共静态void main(字符串[]args)
{
发射(args);
}
@凌驾
public void start(Stage)引发异常
{
按钮启动=新按钮(“启动”);
开始。重新安置(250125);
start.setOnAction(
新的EventHandler()
{
@凌驾
公共无效句柄(ActionEvent evt)
{
PathTransition transition=getTransition();
transition.play();
}
}
);
群根=
新组(Statlabel 1、Statlabel 2、Periabel、start);
舞台场景(新场景(根,350200));
stage.show();
}
自有品牌
getLabel(字符串文本、双xco、双yco、彩色)
{
标签=新标签(文本);
重新定位(xco、yco);
标签。setTextFill(颜色);
label.setFont(Font.Font(“Arial”,20));
退货标签;
}
私有路径转换
getTransition()
{
标签from=statLabel1;
标签也=statLabel2;
持续时间=持续时间。毫秒(3000);
double startX=from.getLayoutX();//+30;
double startY=from.getLayoutY();//+30;
System.out.println(“从布局:“+startX+”,“+startY”);
System.out.println(“From Offset:+From.getTranslateX())
+“,”+from.getTranslateX());
double-endX=too.getLayoutX();//+30;
double-endY=too.getLayoutY();//+30;
System.out.println(“到布局:“+endX+”,“+endY”);
System.out.println(“To Offset:+too.getTranslateX())
+“,”+too.getTranslateX());
MoveTo start=新的MoveTo(startX,startY);
System.out.println(“MoveTo:“+start.getX()+”,“+start.getY());
ArcTo end=新的ArcTo();
end.setX(endX);
完.塞蒂(完);
结束。setRadiusX(100);
结束。setRadiusY(100);
System.out.println(“ArcTo:+end.getX()+”,“+end.getY());
System.out.println(“**********”);
路径路径=新路径();
path.getElements().addAll(开始、结束);
PathTransition transition=新的PathTransition();
转换。设置持续时间(持续时间);
transition.setPath(路径);
transition.setNode(periabel);
transition.setOnFinished(
新的EventHandler()
{
公共无效句柄(ActionEvent evt)
{
System.out.println(“Landed:+periabel.getLayoutX()
+“,”+periabel.getLayoutY());
System.out.println(“偏移量:+periabel.getTranslateX()
+“,”+periabel.getTranslateY());
}
}
);
回归过渡;
}
}

您的代码有两个问题:

  • PathTransition在节点自身的坐标系中移动节点。因此,如果节点的layoutX/Y设置为50,50,就像Periabel设置的那样,它将被移位

  • PathTransition按节点的中心移动节点,而不是按左上角移动节点

  • 下一个代码将修复您的问题:

    private PathTransition getTransition() {
        Label from = statLabel1;
        Label too = statLabel2;
        Duration duration = Duration.millis(3000);
    
        // fix problem (1)
        periLabel.relocate(0, 0);
        // fix problem (2)
        double startX = from.getLayoutX() + from.getBoundsInLocal().getWidth() / 2;
        double startY = from.getLayoutY() + from.getBoundsInLocal().getHeight() / 2;
    
        double endX = too.getLayoutX() + too.getBoundsInLocal().getWidth() / 2;
        double endY = too.getLayoutY() + too.getBoundsInLocal().getHeight() / 2;