2017-05-04 1 views
-1

javafx.scene.control.TextField에 java.lang.reflect.Field를 발행 할 수 있습니까? 예를 들어javafx.scene.control.TextField에 java.lang.reflect.Field를 발행 할 수 있습니까?

:

Field[] nodes; 
nodes = clase.getDeclaredFields(); 

for (Field n : nodes) 
    if (n.getType().getSimpleName().equals("TextField")) 
    ((TextField)((Object) n)).setText("Text"); 
+0

No :'Field'는'TextField'가 아니며 결코 될 수 없습니다. (그것은'TextField' 타입 일 수 있지만, 같은 것을 의미하지는 않습니다.) 실제로 무엇을하려고합니까? –

+0

Field가 TextField가 아니라는 것을 알고 있습니다. 어떤 속성을 수정하기 위해 모든 TextField를 얻으려고합니다. 그래서 Reflection이 클래스에 선언 된 모든 TextField를 얻으려고합니다. – R3ing

+0

이미 알고 있다면,'Field'를'TextField'로 캐스팅하려고하는 코드를 왜 게시하고 있습니까? 당신은'ClassCastException'을 던질 것을 보장합니다. 왜 여기서 반사를 사용합니까? 왜 컨트롤러의 각 텍스트 필드에서 메서드를 호출하지 않습니까? 실제 문제가 무엇인지 설명하기 위해 질문을 편집해야합니다. –

답변

1

당신이 TextField의를 수정하려는 경우, 당신은 그 필드의 값을 검색 (그리고 TextField이 값을 캐스팅)해야합니다.

다음 예는 접근 방식을 설명한다 :

private TextField t1 = new TextField(); 
private TextField t2 = new TextField(); 

@Override 
public void start(Stage primaryStage) { 
    Button btn = new Button("Say 'Hello World'"); 
    btn.setOnAction((ActionEvent event) -> { 
     Object object = this; 
     Class clazz = object.getClass(); 
     for (Field field : clazz.getDeclaredFields()) { 
      if (field.getType().getName().equals("javafx.scene.control.TextField")) { 
       try { 
        // get field value here 
        TextField textField = (TextField) field.get(object); 

        if (textField != null) { 
         textField.setText("Hello World"); 
        } 
       } catch (IllegalArgumentException | IllegalAccessException ex) { 
        Logger.getLogger(ReflectTest.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 

    }); 

    VBox root = new VBox(); 
    root.getChildren().addAll(btn, t1, t2); 

    Scene scene = new Scene(root); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

대단히 감사합니다. James_D는 내가 미쳤다고 말했고, 당신은 그렇게 할 수 없었다. java.lang.reflect.Field를 javafx.scene.control.TextField로 변환하라. 다시 한번 감사드립니다. – R3ing

+0

@ R3ing 나는 TextField에'Field'를 할당 할 수 없다고 말했습니다 : 당신은 할 수 없습니다 - 당신은이 답 에서처럼 값을 가져와야합니다. 그러나 저는이 접근법에 아무런 요점도 없다고 주장하면서 (여전히 논쟁 중입니다.) 이와 같은 접근 방식이 매우 많은 텍스트 필드가 있다면 고려해 볼만한 가치가 있다고 가정하면 어쨌든 필드로 개별적으로 선언하고 싶지 않을 것입니다. –

0

반사 아마 이것에 정말 나쁜 방법입니다. 많은 문제 중 하나는 코드가으로 작성된 방법에 따라 달라질 수있는 기능을 에 종속시키는 것입니다. 특히 각 텍스트 필드가 특정 클래스의 특정 인스턴스 필드에 저장되어 있다고 가정합니다. 구현을 변경하면 (예 : 따라서 텍스트 필드를 직접 유지하는 대신 데이터 필드에 유지하면 기능이 중단됩니다. 명확한 이유 때문에 코드의 실제 구현과 밀접하게 결합 된 코드를 작성하는 것은 나쁜 습관입니다.

한 가지 더 나은 방법은 모든 텍스트 필드를 목록 (또는 다른 데이터 구조)에 넣는 것일 뿐이므로 필요한 모든 것을 쉽게 할 수 있습니다. 예 :

public class MyForm { 

    private GridPane view ; 

    private String[] messages = {"First name:", "Last name", "Email"} ; 

    private List<TextField> textFields ; 

    public MyForm { 

     view = new GridPane(); 
     textFields = new ArrayList<>(); 

     for (int r = 0; r < messages.length ; r++) { 
      view.addRow(r, new Label(messages[r]), createTextField(messages[r])); 
     } 
    } 

    private TextField createTextField(String text) { 
     TextField textField = new TextField(); 
     textField.setPromptText(text); 
     textFields.add(textField); 
     return textField ; 
    } 

    public void processTextFields() { 
     textField.forEach(tf -> tf.setText("Hello")); 
    } 
} 

또 다른 접근법은 CSS 조회를 사용하는 것입니다. myForm 모든 텍스트 필드의 상위 일부 노드의 경우 :

myForm.lookupAll(".text-field").forEach(node -> { 
    TextField textField = (TextField)node ; 
    textField.setText("Hello"); 
}); 

만 조회가 CSS는 기본적으로 (적용되었습니다 때까지 작동하지 않습니다 CSS주의 장면이 렌더링 된 후,이 의미 처음으로).

textFieldParentNode.getChildrenUnmodifiable().stream() 
    .filter(TextField.class::isInstance) 
    .map(TextField.class::cast) 
    .forEach(tf -> tf.setText("Hello")); 
: 모든 텍스트 필드는 모든 (예 : 첫 번째 예에서 격자 창으로) 단일 직접 부모에 포함되어있는 경우

또 다른 방법은, 텍스트 필드를 자식 노드를 반복하고 필터링하는 것