2017-04-19 97 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

不知道,爲什麼它沒有它的工作,但感謝您的幫助。 –