Javafx-单击Gridpane内部打印出窗格而不是Textfield



我正在尝试在Javafx中制作Sudoku游戏。我使用Gridpane和Textfield制作了9x9网格。

现在,当用户单击其中时,我想更改文本字段的背景颜色。为了检查每个人都很好,我将目标od the Mouseevent固定。

我的问题是,当我单击Textfield的中心时,目标是窗格,当我单击其他位置时,目标是我的Gridpane,背景颜色正在改变。

我该怎么办?我不知道该怎么做!

public class SudokuGrid {
public static final int GRID_SIZE = 9;
private TextField[][] sudokuCells;
private GridPane sudokuGrid;
public SudokuGrid () {
    sudokuCells = new TextField[GRID_SIZE][GRID_SIZE];
    createSudokuGrid();
    for (int row = 0; row < GRID_SIZE; row++) {
        for(int col = 0; col < GRID_SIZE; col++) {
            sudokuCells[row][col] = new TextField() {
                  @Override
                    public void replaceText(int start, int end, String text) {
                        // If the replaced text would end up being invalid, then simply
                        // ignore this call!
                        if (text.matches("[1-9]|\s")) {
                            super.setText(text);
                        }
                    }
                };
            sudokuCells[row][col].setPrefSize(60, 60);
            sudokuCells[row][col].setStyle("-fx-background-color: yellow;");
            sudokuGrid.add(sudokuCells[row][col], col, row);
            sudokuGrid.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent e) {
                    Object source = e.getTarget();
                    System.out.println(source);
                    if(source instanceof TextField) {
                        ((TextField) source).setStyle("-fx-background-color: green;");
                    }
                }
                });
        }
    }   
    sudokuGrid.setPrefSize(270, 270); // 30 * 9
    sudokuGrid.setGridLinesVisible(true);
}
private void createSudokuGrid() {
    sudokuGrid = new GridPane();
    for (int i = 0; i  < GRID_SIZE; i++) {
        RowConstraints rc = new RowConstraints();
        rc.setVgrow(Priority.ALWAYS) ; // allow row to grow
        rc.setFillHeight(true); // ask nodes to fill height for row
        // other settings as needed...
        sudokuGrid.getRowConstraints().add(rc);
        ColumnConstraints cc = new ColumnConstraints();
        cc.setHgrow(Priority.ALWAYS) ; // allow column to grow
        cc.setFillWidth(true); // ask nodes to fill space for column
        // other settings as needed...
        sudokuGrid.getColumnConstraints().add(cc);
    }
}

事件的source是您设置事件过滤器的对象;即在这种情况下是sudokuGrid。所以条件

if (source instanceof TextField)

您的处理程序永远不会是真实的,因为唯一可能的来源是sudokuGrid

如果要更改文本字段的背景颜色,则可以将事件过滤器添加到文本字段本身:

TextField sudokuCell = sudokuCells[row][col];
sudokuCell.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> 
    sudokuCell.setStyle("-fx-background-color: green;"));

最好仍然是响应文本字段的重点属性的更改(因为使用鼠标侦听器如果用户使用选项卡键导航到不同的文本字段,则不会更改背景(:

TextField sudokuCell = sudokuCells[row][col];
sudokuCell.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
    if (isNowFocused) {
        sudokuCell.setStyle("-fx-background-color: green;");
    } else {
        sudokuCell.setStyle("");
    }
});

,甚至更好的就是使用外部CSS文件来执行此操作:

sudoku-grid.css:

.text-field:focused {
    -fx-background-color: green ;
}

,然后在您的Java代码中将CSS文件与网格相关联:

sudokuGrid.getStyleSheets().add("sudoku-grid.css");

并完全卸下处理程序。

最新更新