在GridPane上重置以前单击的标签

时间:2016-11-24 01:47:47

标签: java javafx labels gridpane

我正在创建一个迷你游戏,其中包含一组以黑色开头的标签,但一旦点击就会变为黄色。我想要发生的是,当前点击的标签变为黄色时,之前点击的标签会变回黑色。

我这样做的问题是如何将之前点击的标签变回黑色。我每次点击一个标签并尝试使用不同的类来做不同的事情时都尝试创建一个新的GridPane,但没有一个有效。我还尝试在创建GridPane时创建2D标签数组,但我无法使用它来重置以前的标签。

这是我的代码,我哪里错了?

package application;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.InputEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        BorderPane borderpane = new BorderPane();
        GridPane grid = setGrid();

        borderpane.setTop(grid);
        Scene sc = new Scene(borderpane, 400, 400);
        sc.getStylesheets().add("application/application.css");
        primaryStage.setScene(sc);
        primaryStage.show();
    }

    public GridPane setGrid() {
        GridPane grid = new GridPane();

        for (int row = 0; row < 5; row++)
            for (int col = 0; col < 5; col++) {
                Label l = new Label();
                l.setPrefHeight(100);
                l.setPrefWidth(100);
                l.getStyleClass().add("box");

                l.setOnMouseClicked(new EventHandler<InputEvent>() {
                    @Override
                    public void handle(InputEvent arg0) {
                        l.getStyleClass().add("clicked");
                    }
                });

                grid.add(l, col, row);
        }
        return grid;
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

}

1 个答案:

答案 0 :(得分:0)

你做错了什么?显然,在您的代码中,您不会尝试在任何地方删除样式类。当然,如果您所做的一切都是一遍又一遍地添加样式类,那么任何东西都不会回到正常状态。

要从先前单击的节点中删除样式类,您需要将此信息存储在某处,例如在EventHandler中,用于所有标签。请注意,不是反复删除/添加样式类,而是更适合使用伪类,这允许您轻松添加/删除类,而无需阻止类被多次添加。因此,在下面的代码中,我使用样式类注释掉了部分,并使用伪类替换它们:

private static final PseudoClass CLICKED = PseudoClass.getPseudoClass("clicked");

public GridPane setGrid() {
    GridPane grid = new GridPane();


    EventHandler<MouseEvent> handler = new EventHandler<MouseEvent>() {

        private Label lastLabel;

        @Override
        public void handle(MouseEvent event) {
            Label currentLabel = (Label) event.getSource();

            // currentLabel.getStyleClass().add("clicked");

            if (lastLabel != null) {
                // lastLabel.getStyleClass().remove("clicked");
                lastLabel.pseudoClassStateChanged(CLICKED, false);
            }
            currentLabel.pseudoClassStateChanged(CLICKED, true);

            lastLabel = currentLabel;
        }

    };

    for (int row = 0; row < 5; row++) {
        for (int col = 0; col < 5; col++) {
            Label l = new Label();
            l.setPrefHeight(100);
            l.setPrefWidth(100);
            l.getStyleClass().add("box");

            l.setOnMouseClicked(handler);

            grid.add(l, col, row);
        }
    }
    return grid;
}

CSS

使用样式类

.box.clicked {
    -fx-background-color: yellow;
}
.box {
    -fx-background-color: black;
}

使用伪类

.box:clicked {
    -fx-background-color: yellow;
}
.box {
    -fx-background-color: black;
}

请注意,在这种情况下,由于您不使用Label的任何文字,因此您只需使用Region即可达到相同的效果。