我正在尝试在javaFX中执行“ memoryGame”。我现在要处理的是单击此按钮后,使用CSS在一个函数中两次更改按钮的背景。
在此游戏中,我创建一个GridPane,并在每个单元格中放置带有图片的按钮,每张图片都有两个按钮。在它上面,我放了另一个空按钮。如果单击一个按钮,它将变为透明,因此我可以看到图片。然后,我单击了另一个按钮,同样的事情发生了。现在,如果图片相同,我会得到一点,透明度不会改变,但是如果图片不同,程序将等待一秒钟,将两个按钮都更改为其主要状态(不透明)。
问题是,如果我更改按钮的样式,请稍等片刻再更改一次,此按钮在此功能期间不会更改其样式,但是会在功能结束后发生。因此,我们看不到第一个样式,只能看到最后一个样式。
我发送的代码是简化版本,仅对一个按钮有效。
public void changeTransparent(ActionEvent event) {
butCver01.setStyle("-fx-background-color: transparent");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
butCver01.setStyle("-fx-background-color: green");
}
现在,当我们单击butCver01时,一秒钟后它将变为绿色。
答案 0 :(得分:3)
正如我在评论中提到的那样, JavaFX Application Thread 无法在仍执行您的方法时安排下一帧渲染(即“脉冲”)。使用Thread.sleep
会阻塞FX线程,这使事实更加复杂,{em}会阻止FX线程执行任何操作,更不用说安排下一个脉冲了。阻止的FX线程等于冻结的UI,您的用户将无法再单击任何卡来尝试进行匹配。
您应该使用animation API在FX线程上“随着时间的推移”执行操作。动画“异步”执行(在FX线程上),这意味着在动画运行时可以处理其他动作。启动动画的调用也会立即返回。这是一个示例,该示例将显示矩形下方的形状一秒钟;但是,无法确定是否显示两个匹配的形状,一次只显示两个形状,依此类推。
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
HBox box = new HBox(10, createCard(true), createCard(true), createCard(false));
box.setPadding(new Insets(100));
primaryStage.setScene(new Scene(box));
primaryStage.show();
}
private StackPane createCard(boolean circle) {
Shape shape;
if (circle) {
shape = new Circle(50, Color.FORESTGREEN);
} else {
// create triangle
shape = new Polygon(0, 0, 50, 100, -50, 100);
shape.setFill(Color.FIREBRICK);
}
Rectangle cover = new Rectangle(0, 0, 100, 150);
cover.mouseTransparentProperty()
.bind(cover.fillProperty().isEqualTo(Color.TRANSPARENT));
cover.setOnMouseClicked(event -> {
event.consume();
cover.setFill(Color.TRANSPARENT);
PauseTransition pt = new PauseTransition(Duration.seconds(1));
pt.setOnFinished(e -> cover.setFill(Color.BLACK));
pt.playFromStart();
});
return new StackPane(shape, cover);
}
}