2017-04-19 107 views
0

我想在JavaFX中制作Sudoku游戏。我使用GridPane和TextField制作了9x9网格。JavaFX - 点击GridPane内部打印出的窗格而不是TextField

现在我想改变TextField的背景颜色,当用户点击它时。为了检查everyting是否正常,我正在捕获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); 
    } 

} 

回答

1

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

if (source instanceof TextField) 

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

如果你想改变文本框的背景颜色,你可以将事件过滤器添加到文本字段本身:

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

更妙的是将在文本字段的聚焦特性的变化做出反应(因为使用鼠标监听器,如果用户使用Tab键导航到不同的文本字段不会改变背景):

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

更妙的也只是使用一个外部CSS文件来做到这一点:

数独grid.css:

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

,然后在Java代码中关联的CSS文件与电网:

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

和完全删除处理程序。

+0

谢谢。我使用了最后一个选项。这似乎是最简单的。但我必须添加这个代码'sudokuCells [row] [col] .getStyleClass()。add(“text-field”);'使其工作。 –

+0

@ValentinEmilCudelcu它应该没有这个工作。 'TextField'有一个'text-field'的样式类[默认情况下](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#textfield )。 (顺便说一句,如果答案是正确的,如果它回答的问题。) –

+0

不知道,为什么它没有它的工作,但感谢您的帮助。 –