gpt4 book ai didi

java - 如何在接受下一个 MouseEvent 之前等待当前 MouseEvent EventHandler 结束?

转载 作者:行者123 更新时间:2023-12-02 04:19:38 25 4
gpt4 key购买 nike

我的棋盘游戏取得进展,因此只需单击鼠标,就会执行一些任务,例如播放一些动画、接收棋盘的新 Pane (我问了我的最后一个问题,现在效果很好)、对玩家进行更改数据等

所以,这是我的事件处理程序

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 对象,其中包含板中每个单元格的其他 Pane 、动画 Pane 等。

处理一个鼠标事件需要 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 类数组,因为我需要很多这样的 Pane ,并且需要跟踪每个 Pane 。

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

现在这个playAnimation()方法就像一个动画启动。

此 Pane 上的动画完成后,会根据玩家的进度对棋盘进行更改,如果需要的话...此 playAnimation()方法将调用 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() .

编辑2:

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

编辑3:

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

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

当时间轴动画开始播放时,我将其设置为 true ,当时间轴动画完成时,我将其设置为 false .

在主类中(例如 Game ),我添加了一个 BooleanBinding anyAnimating 。我绑定(bind)了anyAnimatingisAnimating每个Animations使用我说我创建的数组的对象。

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

最后我使用了 anyAnimating 的值正如 Brad 建议的那样,作为 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);});

}
});

关于java - 如何在接受下一个 MouseEvent 之前等待当前 MouseEvent EventHandler 结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32925149/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com