java - 事件处理方法无法正常工作

标签 java user-interface javafx event-handling

我正在 Eclipse 中使用 JavaFX 创建 GUI 应用程序。在此应用程序中,我正在创建一个正方形 map ,您可以在其中在填充空间和空白空间之间切换正方形。我希望程序允许用户切换除边缘以外的所有方 block ,但由于某种原因,我的处理方法允许我切换所有方 block 。我只是想知道我的处理程序方法是否正确。提前感谢您的帮助。

GUI 应该是这样的
enter image description here

这是我的 GUI 类,名为 mazeGuiPane 包lab8;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MazeGuiPane extends Application {
    private GridPane grid = new GridPane();
    private BorderPane border = new BorderPane();
    private Scene sc = new Scene(border);
    public Label[][] labelGridArray = new Label[20][20];
    private StreetMap map = new StreetMap();
    int col;
    int row;

    public void start(Stage primary) {

        sc.getStylesheets().add("/styles/style.css");
        grid.getStyleClass().add("grid-style");
        border.getStyleClass().add("border-style");
        Label mainTitle = new Label("Map Of Pamplona");
        mainTitle.getStyleClass().add("white-text");
        Button butt = new Button("RUN!");
        VBox vBox = new VBox();
        HBox buttHBox = new HBox();
        HBox titleBox = new HBox();
        VBox titleVBox = new VBox();
        VBox buttVBox = new VBox();

        map.makeGrid();

        for (col = 0; col < 20; col++) {
            for (row = 0; row < 20; row++) {
                Label square = new Label();
                if (map.gridArray[col][row].getValue() == ' ') {
                    square.getStyleClass().add("default-box");
                } else if (map.gridArray[col][row].getValue() == 'S') {
                    square.setText("Start");
                    square.getStyleClass().add("start-end");
                } else if (map.gridArray[col][row].getValue() == 'E') {
                    square.setText("End");
                    square.getStyleClass().add("start-end");
                } else {
                    square.getStyleClass().add("wall");
                }

                square.setOnMouseClicked(new EventHandler<MouseEvent>() {
                    @Override
                    public void handle(MouseEvent t) {
                        row = GridPane.getRowIndex(square);
                        col = GridPane.getColumnIndex(square);
                        for (int col = 1; col < 19; col++) {
                            for (int row = 1; row < 19; row++) {
                                if (map.gridArray[col][row].getTier() != 0
                                    || map.gridArray[col][row].getTier() != 19
                                    || map.gridArray[col][row].getColumn() != 0
                                    || map.gridArray[col][row].getColumn() != 19) {
                                    if(map.gridArray[col][row].getValue() == 'W'){
                                        square.getStyleClass().removeAll("wall");
                                        square.getStyleClass().add("default-box");
                                        map.gridArray[col][row].setTier(row); 
                                        map.gridArray[col][row].setColumn(col); map.gridArray[col][row].setValue(' ');
                                    }
                                    else {
                                        square.getStyleClass().removeAll("default-box");
                                        square.getStyleClass().add("wall");
                                        map.gridArray[col][row].setTier(row); 
                                        map.gridArray[col][row].setColumn(col);
                                        map.gridArray[col][row].setValue('W');

                                    }
                                }
                            }
                        }
                    }
                });

                labelGridArray[col][row] = square;
                grid.add(square, col, row);
            }
        }
        titleBox.getStyleClass().add("title");
        titleBox.getChildren().add(mainTitle);
        titleVBox.getChildren().add(titleBox);

        buttHBox.getStyleClass().add("button-style");
        buttHBox.getChildren().add(butt);
        buttVBox.getChildren().add(buttHBox);

        vBox.getChildren().add(grid);

        border.setTop((titleBox));
        border.setCenter(vBox);
        border.setBottom(buttVBox);

        primary.setScene(sc);
        primary.show();
    }

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

最佳答案

单击标签时,您将为除边框标签之外的每个标签更新此标签。这可能不是您想要的。

此外,您写入 columnrow 字段的值似乎没有在任何地方使用。您应该删除它们并坚持使用局部变量。

如果您不想在单击边框上的标签时触发更新,则可以不为这些节点注册监听器。将标签创建和处理程序注册移动到不同的循环:

for (int col = 0; col < 20; col++) {
    for (int row = 0; row < 20; row++) {
        Label square = new Label();
        if (map.gridArray[col][row].getValue() == ' ') {
            square.getStyleClass().add("default-box");
        } else if (map.gridArray[col][row].getValue() == 'S') {
            square.setText("Start");
            square.getStyleClass().add("start-end");
        } else if (map.gridArray[col][row].getValue() == 'E') {
            square.setText("End");
            square.getStyleClass().add("start-end");
        } else {
            square.getStyleClass().add("wall");
        }
        labelGridArray[col][row] = square;
        grid.add(square, col, row);
    }
}
for (int col = 1; col < 19; col++) {
    final int finalCol = col; // copy accessible from handler
    for (int row = 1; row < 19; row++) {
        final int finalRow = row; // copy accessible from handler
        final Label square = labelGridArray[col][row];
        square.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent t) {
               if (map.gridArray[finalCol][finalRow].getValue() == 'W'){
                    square.getStyleClass().remove("wall");
                    square.getStyleClass().add("default-box");
                    map.gridArray[finalCol][finalRow].setTier(finalRow); 
                    map.gridArray[finalCol][finalRow].setColumn(finalCol);
                    map.gridArray[finalCol][finalRow].setValue(' ');
                } else {
                    square.getStyleClass().remove("default-box");
                    square.getStyleClass().add("wall");
                    map.gridArray[finalCol][finalRow].setTier(finalRow); 
                    map.gridArray[finalCol][finalRow].setColumn(finalCol);
                    map.gridArray[finalCol][finalRow].setValue('W');
                }
            }
        });
    }
}

附加说明:

  • 除非 getColumngetTier 返回不同的值,否则以下析取始终会产生 true,因为原始值不能同时等于 019

    if (map.gridArray[col][row].getTier() != 0
        || map.gridArray[col][row].getTier() != 19
        || map.gridArray[col][row].getColumn() != 0
        || map.gridArray[col][row].getColumn() != 19) {
    
  • 最好使用枚举而不是 char 作为值。这允许您向对象添加数据/方法,还可以防止您意外使用错误的值或错误的大小写。

    public enum CellType {
        EMPTY("", "default-box"),
        START("Start", "start-end"),
        END("End", "start-end"),
        WALL("", "wall");
    
        private final String styleClass;
        private final String text;
    
        CellType(String text, String styleClass) {
            this.text = text;
            this.styleClass = styleClass;
        }
    
        public String getStyleClass() {
            return styleClass;
        }
    
        public String getText() {
            return text;
        }
    
        public Values inverted() {
            // this requires the values to be kept in this order
            CellType[] vals = values();
            return vals[vals.length - 1 - ordinal()];
        }
    }
    

    这允许您简化处理程序中的代码:

    CellType type = map.gridArray[finalCol][finalRow].getValue();
    square.getStyleClass().remove(type.getStyleClass());
    type = type.inverted();
    map.gridArray[finalCol][finalRow].setValue(type);
    square.getStyleClass().add(type.getStyleClass());
    
    // are the following lines really necessary?
    map.gridArray[finalCol][finalRow].setTier(finalRow);
    map.gridArray[finalCol][finalRow].setColumn(finalCol);
    

关于java - 事件处理方法无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49827696/

相关文章:

objective-c - setPatternPhase : in an NSSplitView for NSColor using colorWithPatternImage: 的问题

java - GUI 停止工作,即使它在自己的线程中并且未调用 Thread.sleep()

button - 将 JavaFX 按钮定位在特定位置

java - org.apache.commons.fileupload.disk.DiskFileItem 没有正确创建?

java - JAX-RS 和长轮询

java - 像 Hyperink 这样的 GWT 标签

java - 如何在考虑长度 > 1 的字符时比较字符串的每个字符?

c++ - 避免多个 bool 值的优雅方法?

java - JavaFX TreeView 的嵌套路径

Java:制作基于网格的棋盘游戏