【问题标题】:Resetting Previously Clicked Label on GridPane重置 GridPane 上先前单击的标签
【发布时间】:2016-11-24 01:47:47
【问题描述】:

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

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

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

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);
    }

}

【问题讨论】:

    标签: java javafx labels gridpane


    【解决方案1】:

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

    要从先前单击的节点中删除样式类,您需要将此信息存储在某处,例如在您用于所有标签的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;
    }
    

    请注意,在这种情况下,由于您没有使用带有 Labels 的任何文本,因此您可以改为使用 Region 来达到相同的效果。

    【讨论】:

      猜你喜欢
      • 2018-04-21
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-26
      • 2012-10-23
      • 2016-05-28
      相关资源
      最近更新 更多