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