在我的棋盘游戏上取得进步,因此,单击鼠标即可执行一些任务,例如播放一些动画,为棋盘接收新窗格(我问了我的最后一个问题,现在很好用),更改玩家数据等。

所以,这是我的EventHandler

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        //make changes to player data
        //receive new panes for the board
        //make some gui changes
        //play some animations
    }
});


这里的grid是GridPane对象,其中包含板的每个单元的其他窗格,动画的窗格等。

一次鼠标事件将需要2-3秒的时间来处理。在进行此操作的同时,我发现与已经进行的鼠标单击同时也将开始处理另一次鼠标单击。

我想要的是在第一个鼠标事件完成之前,不应处理另一个鼠标事件。如果将收到的任何点击都丢弃,那将更好。

我尝试使用线程:

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        Thread t = new Thread(new Runnable() {
            public void run() {
                //completing the necessary tasks here
            }
        });
        t.start();
        t.join();
    }
});


但是,如果我使用线程,则不会发生GUI更改(不知道为什么,我以许多不同的方式对其进行了测试,但始终无法进行GUI更改),所以我猜这行不通。

那么,在处理一个鼠标事件时,我该怎么做才能不引起任何鼠标点击?我认为这个问题不需要更多代码,但是如有必要,我将编辑并添加一些代码。

编辑:

class Animations {
    public Pane getAnimationPane() {
        //returns Pane which would be used for transition
    }

    public void playAnimation() {
        //called only when the timeline transition is to be played
    }
}


因此,我制作了一个Animations类的数组,因为我需要很多这样的窗格,并且需要跟踪每个窗格。

当我需要播放动画时,我调用playAnimation()方法。

现在,此playAnimation()方法就像一个动画开始。

在此窗格上的动画完成之后,将根据玩家的进度对棋盘进行更改,并且如果需要...此playAnimation()方法将调用其他几个Animation对象的playAnimation()方法。

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        //make changes to player data
        //receive new panes for the board
        //make some gui changes
        //play some animations
        someAnimationObject.playAnimation();
    }
});


这可能会深至10-20(如果网格很大,则更大)用于其playAnimation()的其他Animation对象。

编辑2:

playAnimation()Animations可以在0-8个其他Animations对象上调用playAnimation()。而且这可能会继续下去。

编辑3:

我终于解决了我的问题,这就是我的做法。

我在SimpleBooleanProperty类(实例变量,即非静态)中添加了isAnimating Animations,默认情况下将其设置为false

时间线动画开始播放时,将其设置为true,时间线动画完成时,将其设置为false

在主类中(例如Game),我添加了BooleanBinding anyAnimating
我使用我说的数组将anyAnimating绑定到每个isAnimating对象的Animations

anyAnimating = Bindings.or(anyAnimating, AnimationsObj[i][j].isAnimatingProperty());


最后,正如Brad建议的那样,我将anyAnimating的值用作MouseEvent EventHandler中的标志。

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        if(!anyAnimating.get()){
            //make changes to player data
            //receive new panes for the board
            //make some gui changes
            //play some animations
        }
    }
});

最佳答案

我不太确定这里的细节,因为关于动画的管理方式,您的问题没有很多细节,但这应该可以为您提供总体思路。

将标记添加到您的Animations类中,以指示动画是否正在进行中:

class Animations {

    private ReadOnlyBooleanWrapper animating = new ReadOnlyBooleanWrapper() ;

    public ReadOnlyBooleanProperty animatingProperty() {
        return animating.getReadOnlyProperty();
    }

    public boolean isAnimating() {
        return animatingProperty().get();
    }

    public Pane getAnimationPane() {
        //returns Pane which would be used for transition
    }

    public void playAnimation() {
        //called only when the timeline transition is to be played

        Animation animation = ... ;
        animation.statusProperty().addListener((obs, oldStatus, newStatus) ->
            animating.set(newStatus == Animation.Status.RUNNING));

        animation.play(); // etc


    }
}


现在你可以做

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {

        if (! someAnimationObject.isAnimating()) {
            //make changes to player data
            //receive new panes for the board
            //make some gui changes
            //play some animations
            someAnimationObject.playAnimation();
        }
    }
});


也许

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {

        grid.setDisable(true);

        //make changes to player data
        //receive new panes for the board
        //make some gui changes
        //play some animations
        someAnimationObject.animatingProperty().addListener((obs, wasAnimating, isNowAnimating) -> {
            if (! isNowAnimating) {
                grid.setDisable(false);
            }
        });
        someAnimationObject.playAnimation();
    }
});


另一种方法是让playAnimation()接受在动画完成时(或在所有动画都完成时,如果要执行多个动画)执行的回调。

这看起来像:

class Animations {


    public Pane getAnimationPane(Runnable finishedCallback) {
        //returns Pane which would be used for transition
    }

    public void playAnimation() {
        //called only when the timeline transition is to be played

        Animation animation = ... ;
        animation.statusProperty().addListener((obs, oldStatus, newStatus) -> {
            if (newStatus == Animation.Status.STOPPED) {
                finishedCallback.run();
            }
        });

        animation.play(); // etc


    }
}


然后,您的事件处理代码可以执行以下操作:

// declared at instance level:
private boolean animating = false ;

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        if (! animating) {
            animating = true ;
            //make changes to player data
            //receive new panes for the board
            //make some gui changes
            //play some animations
            someAnimationObject.playAnimation( () -> {animating = false ;});
        }
    }
});


要么

grid.setOnMouseReleased(new EventHandler<MouseEvent> () {
    public void handle(MouseEvent me) {
        grid.setDisable(true);
        //make changes to player data
        //receive new panes for the board
        //make some gui changes
        //play some animations
        someAnimationObject.playAnimation( () -> {grid.setDisable(false);});

    }
});

09-28 04:38