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

时间:2018-04-14 03:49:10

标签: java user-interface javafx event-handling

我正在Eclipse中使用JavaFX创建一个GUI应用程序。在这个应用程序中,我创建了一个正方形的地图,您可以在填充空间和空白空间之间切换正方形。我希望程序允许用户切换除边缘上的所有方块,但由于某种原因,我的句柄方法允许我切换所有方块。我只是想知道我的处理程序方法是否正常。请提前获取帮助。

这就是GUI的外观 enter image description here

这是我的名为mazeGuiPane的GUI类     package 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);
    }
}

2 个答案:

答案 0 :(得分:0)

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

此外,您写入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,因为原始值不能等于0和{{1} }}

    19
  • 最好使用枚举而不是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()];
        }
    }
    

答案 1 :(得分:0)

以下是MCVE展示问题的方式。以下代码还演示了根据需要响应鼠标单击的简化实现:

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

public class MazeGuiPane extends Application {

    private int gridSize = 20;
    int col, row;

    @Override
    public void start(Stage primary) {

        StreetMap map = new StreetMap();
        map.makeGrid(gridSize);
        GridPane grid = new GridPane();
        for (col = 0; col < 20; col++) {
            for (row = 0; row < 20; row++) {
                grid.add(map.getGridArray()[row][col], col, row);
            }
        }
        primary.setScene(new Scene(grid));
        primary.show();
    }

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

//represents a single square
class Square extends Label{
    private int squareSize = 20;
    private static final String empty = " ",  wall = "W"; //better use enum

    Square(){   this(empty); }

    Square(String txt){
        setText(txt);
        setStyle("-fx-border-color: black");
        setPrefSize(squareSize,squareSize);
    }

    void toggle() {
        setText( getText().equals(empty) ?  wall : empty);
    }
}

//represents grid of squares
class StreetMap {

    private Label[][] gridArray;

    public void makeGrid(int size) {
        gridArray = new Square[size][size];
        for (int col = 0; col < size; col++) {
            for (int row = 0; row < size; row++) {
                Label square = new Square();
                gridArray[row][col] = square;
                //add handler to those who need to respond to mouse clicks
                if((row > 0) && (row < (size -1)) ) {
                    if((col > 0) && (col < (size -1)) ) {
                        square.setOnMouseClicked(new EventHandler<MouseEvent>() {
                            @Override
                            public void handle(MouseEvent t) {
                                ((Square)square).toggle();
                            }
                        });
                    }
                }
            }
        }
    }

    Label[][] getGridArray() { return gridArray; }
}

修改
一个改进版本,遵循kleopatra的评论:

public class MazeGuiPane extends Application {

    private int gridSize = 20;
    int col, row;

    @Override
    public void start(Stage primary) {

        StreetMap map = new StreetMap();
        map.makeGrid(gridSize);
        GridPane grid = new GridPane();
        for (col = 0; col < 20; col++) {
            for (row = 0; row < 20; row++) {
                grid.add(map.getGridArray()[row][col].getNode(), col, row);
            }
        }

        primary.setScene(new Scene(grid));
        primary.show();
    }

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

//represents a single square
class Square{
    private Label label;
    private int squareSize = 20;
    private static final String empty = " ",  wall = "W"; //better use enum
    private SimpleStringProperty squareText = new SimpleStringProperty();

    Square(){ this(empty); }

    Square(String txt){
        squareText.set(txt);
        label = new Label();
        label.textProperty().bind(squareText);
        label.setStyle("-fx-border-color: black");
        label.setPrefSize(squareSize,squareSize);
    }

    void toggle() {
        squareText.set(squareText.get().equals(empty) ?  wall : empty);
    }

    void addMouseHandler() {
        label.setOnMouseClicked(new EventHandler<MouseEvent>(){
            @Override
            public void handle(MouseEvent t) { toggle();}
        });
    }

    Node getNode() {return label; }
}

//represents grid of squares
class StreetMap {

    private Square[][] gridArray;

    public void makeGrid(int size) {
        gridArray = new Square[size][size];
        for (int col = 0; col < size; col++) {
            for (int row = 0; row < size; row++) {
                Square square = new Square();
                gridArray[row][col] = square;
                //add handler to those who need to respond to mouse clicks
                if((row > 0) && (row < (size -1)) ) {
                    if((col > 0) && (col < (size -1)) ) {
                        square.addMouseHandler();
                    }
                }
            }
        }
    }

    Square[][] getGridArray() { return gridArray; }
}