2017-04-19 11 views
0

JavaFX에서 Sudoku 게임을 만들려고합니다. GridPane과 TextField를 사용하여 9x9 격자를 만들었습니다.JavaFX - GridPane 내부를 클릭하면 TextField가 아닌 Pane이 출력됩니다.

이제 사용자가 TextField를 클릭 할 때 TextField의 배경색을 변경하고 싶습니다. 모든 것이 잘되는지 확인하려면 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입니다. 유일하게 가능한 소스가 sudokuGrid 때문에 그래서 핸들러의 조건

if (source instanceof TextField) 

는 진실하지 않습니다.

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 파일을 사용하는 것입니다 : (사용자가 다른 텍스트 필드로 이동하려면 Tab 키를 사용하는 경우 배경을 변경하지 않습니다 마우스 수신기를 사용하기 때문에)

스도쿠 - grid.css : 그리드와 자바 코드 동료의

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

다음 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). (Btw는 질문에 답하면 답을 정답으로 표시합니다.) –

+0

아무런 아이디어가 없으면 왜 효과가 없지만 도움을 주셔서 감사합니다. –