JavaFX Transition动画等待 [英] JavaFX Transition animation waiting

查看:247
本文介绍了JavaFX Transition动画等待的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如此迅速,我正在做程序,演示用于计算机图形绘制的方法。我需要创建时间轴或行为历史,如(placeVertex(x,y),moveVertex(newX,newY)等)并迭代(向前和向后,自动或手动)



我已经通过使用命令设计模式实现了这一点,但这些命令中很少使用转换。第一个想法是在每个命令之间使用Condition接口的锁定,等待并在 setOnFinished 中发出信号,但它导致gui冻结。



<我尝试了SequentialTransition,但它对我的问题毫无用处 - 无法在转换之间动态更改属性。



是否有可能以某种方式告知生成一个过渡结束,下一个过渡可以在没有GUI冻结和绘图的情况下运行?



谢谢!



编辑:我会尝试简化它所有
这是我的命令界面和其中一个命令:

  public interface Command {
public void execute();
}

公共类MoveVertex实现Command {
public MoveVertex(Data d,Vertex v,double changedX,double changedY){..};

@Override
public void execute(){
Path path = new Path();
path.getElements()。add(new MoveTo(v.getCenterX(),v.getCenterY()));
path.getElements()。add(new LineTo(changedX,changedY));

PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(velocity));
pathTransition.setPath(path);
pathTransition.setNode(v.getVertex());

pathTransition.play(); }
}

这些命令存储在我的历史类中,基本上是

  private List< Command>历史; 

我会查看列表并执行命令

  public boolean executeNext(){
if(history.size()!= position){
history.get(position).execute();
position ++;
返回true;
}
返回false;
}

我正试图在下一个命令启动时实现状态。尝试将等待/信号放在两者之间但没有成功。

解决方案

下面的解决方案使用了鼬提出的 onFinished 处理程序移动到一个新节点我们到达下一个位置后的(随机)位置。



通过重用单个Transition而不是在事件处理程序中使用递归,可能会提高效率(并且更容易理解)。可能没有必要为每个动作创建一个新的过渡 - 但是,只要没有成千上万的动作迭代,它应该是可以接受的。

  import javafx.animation。*; 
import javafx.application.Application;
import javafx.event。*;
import javafx.geometry.Point2D;
import javafx.scene。*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape。*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Random;

//动画以随机游走模式永久移动节点。
公共类RandomWalk extends Application {

private static final Random random = new Random(42);

私有静态最终双倍W = 200;
私有静态最终双H = 200;
私有静态最终双R = 10;

private static final Node node = new Circle(
R,Color.FORESTGREEN
);

@Override
public void start(阶段阶段){
//从屏幕中心开始。
node.relocate(W / 2 - R,H / 2 - R);

stage.setScene(新场景(新窗格(节点),W,H));
stage.show();

walk();
}

//按顺序开始从当前位置走到随机点。
private void walk(){
final Point2D to = getRandomPoint();
final Transition transition = createMovementTransition(
node,
to
);

transition.setOnFinished(
walkFrom(to)
);
transition.play();
}

private EventHandler< ActionEvent> walkFrom(最后的Point2D){
返回事件 - > {
//在转换完成之前,完成的处理程序可能被称为帧,
//如果我们在处理程序中重新定位,则会导致故障。
//过渡通过操纵翻译值起作用,
//因此在重新定位节点之前将翻译归零。
node.setTranslateX(0);
node.setTranslateY(0);

//转换完成后,将节点移动到新位置。
//重定位坐标由圆的半径调整。
//对于标准节点,R调整是不必要的
//因为大多数节点位于节点
//的左上角而不是像圆圈一样位于中心是。
node.relocate(
from.getX() - R,
from.getY() - R
);

//生成下一个随机点并进行转换以走到它。
//我宁愿不在这里使用递归,好像你足够长,
//那么你最终会出现堆栈溢出,但我不太确定
//如何在没有递归的情况下做到这一点。
final Point2D next = getRandomPoint();
final Transition transition = createMovementTransition(node,next);
transition.setOnFinished(walkFrom(next));
transition.play();
};
}

//我们使用PathTransition从当前位置移动到下一个位置。
//对于我们正在做的简单的直线运动,
//直接TranslateTransition本来没问题。
// PathTransition仅用于证明此
//可用于通用路径案例,而不仅仅是直线移动。
private Transition createMovementTransition(Node node,Point2D to){
Path path = new Path(
new MoveTo(
0,
0
),
new LineTo(
to.getX() - node.getLayoutX(),
to.getY() - node.getLayoutY()

);

返回新的PathTransition(
Duration.seconds(2),
路径,
节点
);
}

// @return一个边界矩形内的随机位置(0,0,W,H)
//在该点与之间保持R的余量边界矩形边。
private Point2D getRandomPoint(){
返回新的Point2D(
random.nextInt((int)(W - 2 * R))+ R,
random.nextInt((int )(H - 2 * R))+ R
);
}

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


so quicky, I am doing program which demonstrate methods used for computer graph drawing. I need to create timeline or history of actions like ( placeVertex(x,y), moveVertex(newX,newY) etc. ) and iterate through (forward and backwards, automatically or manual)

I already achieved that by using command design pattern but few of these commands are using transitions. First idea was to use Condition interface's lock, await and signal in setOnFinished between each commands but it led to gui freezing.

I tryed SequentialTransition but it's no use for my problem - can't change properties dynamically between transitions.

Is there a possibility to somehow inform generation that one transition ended and next can run without GUI freezing and drawing?

Thanks!

edit: I ll try to simplify it all Here is my Command interface and one of these commands:

 public interface Command {
        public void execute();
  }

 public class MoveVertex implements Command {
        public MoveVertex(Data d, Vertex v, double changedX, double changedY){..};

        @Override
        public void execute() {         
            Path path = new Path();         
            path.getElements().add(new MoveTo(v.getCenterX(), v.getCenterY()));
            path.getElements().add(new LineTo(changedX, changedY));

            PathTransition pathTransition = new PathTransition();   
            pathTransition.setDuration(Duration.millis(velocity)); 
            pathTransition.setPath(path);   
            pathTransition.setNode(v.getVertex());

            pathTransition.play();  }
  }

These Commands are stored in my history class which is basically

private List<Command> history;

And I do going through the list and executing Commands

public boolean executeNext() {
    if (history.size() != position) {
        history.get(position).execute();
        position++;
        return true;
    }
    return false;
}

And I am trying to achieve state when next Command is started only if previous finished. Tryed to put await/signal in between without success.

解决方案

The solution below uses Itachi's suggestion of providing an onFinished handler to move to a node to a new (random) location after we get to the next location.

It could probably be made more efficient (and simpler to understand) by re-using a single Transition rather than using recursion within the event handler. It is probably unnecessary to create a new Transition for each movement - but, as long as there aren't hundreds of thousands of movement iterations, it should be acceptable as is.

import javafx.animation.*;
import javafx.application.Application;
import javafx.event.*;
import javafx.geometry.Point2D;
import javafx.scene.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.util.Random;

// animates moving a node forever in a random walk pattern.
public class RandomWalk extends Application {

    private static final Random random = new Random(42);

    private static final double W = 200;
    private static final double H = 200;
    private static final double R = 10;

    private static final Node node = new Circle(
            R, Color.FORESTGREEN
    );

    @Override
    public void start(Stage stage) {
        // start from the center of the screen.
        node.relocate(W / 2 - R, H / 2 - R);

        stage.setScene(new Scene(new Pane(node), W, H));
        stage.show();

        walk();
    }

    // start walking from the current position to random points in sequence.
    private void walk() {
        final Point2D to = getRandomPoint();
        final Transition transition = createMovementTransition(
                node,
                to
        );

        transition.setOnFinished(
                walkFrom(to)
        );
        transition.play();
    }

    private EventHandler<ActionEvent> walkFrom(final Point2D from) {
        return event -> {
            // Finished handler might be called a frame before transition complete,
            // leading to glitches if we relocate in the handler.
            // The transition works by manipulating translation values,
            // so zero the translation out before relocating the node.
            node.setTranslateX(0);
            node.setTranslateY(0);

            // After the transition is complete, move the node to the new location.
            // Relocation co-ordinates are adjusted by the circle's radius.
            // For a standard node, the R adjustment would be unnecessary 
            // as most nodes are located at the top left corner of the node 
            // rather than at the center like a circle is.
            node.relocate(
                    from.getX() - R,
                    from.getY() - R
            );

            // Generate the next random point and play a transition to walk to it.
            // I'd rather not use recursion here as if you recurse long enough,
            // then you will end up with a stack overflow, but I'm not quite sure
            // how to do this without recursion.
            final Point2D next = getRandomPoint();
            final Transition transition = createMovementTransition(node, next);
            transition.setOnFinished(walkFrom(next));
            transition.play();
        };
    }

    // We use a PathTransition to move from the current position to the next.
    // For the simple straight-line movement we are doing,
    // a straight TranslateTransition would have been fine.
    // A PathTransition is just used to demonstrate that this
    // can work for the generic path case, not just straight line movement.
    private Transition createMovementTransition(Node node, Point2D to) {
        Path path = new Path(
                new MoveTo(
                        0,
                        0
                ),
                new LineTo(
                        to.getX() - node.getLayoutX(),
                        to.getY() - node.getLayoutY()
                )
        );

        return new PathTransition(
                Duration.seconds(2),
                path,
                node
        );
    }

    // @return a random location within a bounding rectangle (0, 0, W, H)
    // with a margin of R kept between the point and the bounding rectangle edge.
    private Point2D getRandomPoint() {
        return new Point2D(
                random.nextInt((int) (W - 2*R)) + R,
                random.nextInt((int) (H - 2*R)) + R
        );
    }

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

这篇关于JavaFX Transition动画等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆