Изменить фон кнопки дважды в рамках одной функции

Я пытаюсь сделать «memoryGame» в javaFX. Сейчас я имею дело с изменением фона кнопки с помощью 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, через одну секунду он станет зеленым.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
149
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как я упоминал в своем комментарии, Поток приложения JavaFX не может запланировать рендеринг следующего кадра (т. е. «импульс»), пока он все еще выполняет ваш метод. Это усугубляется тем фактом, что вы используете Thread.sleep который блоки поток FX, что означает, что он не может выполнять что-нибудь, не говоря уже о планировании следующего импульса. Заблокированный поток FX равен замороженному пользовательскому интерфейсу, и ваш пользователь больше не сможет нажимать на карты, чтобы попытаться найти совпадение.

Вы должны использовать 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);
    }

}

Другие вопросы по теме