2017-05-04 7 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

いいえ: 'Field'は' TextField'ではありません。 (これは 'TextField'型でも構いませんが、それは同じことを意味するものではありません)あなたは実際何をしようとしていますか? –

+0

私はFieldがTextFieldではないことを知っています。私はいくつかのプロパティを変更するためにフォームのTextFieldをすべて取得しようとしているので、Reflectionでクラス内で宣言されたすべてのTextFieldを取得しようとしています。 – R3ing

+0

あなたがすでにそれを知っているなら、なぜ 'Field'を' TextField'にキャストしようとしているのですか?あなたは 'ClassCastException'をスローすることが保証されています。なぜここで反射を使うのですか?なぜコントローラ内の各テキストフィールドで通常の方法でメソッドを呼び出さないのですか?あなたは実際の問題が何であるかを説明するためにあなたの質問を編集する必要があります。 –

答えて

1

あなたがTextField Sを変更したい場合は、それらのフィールドから値を取得(および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")); 
    } 
} 

もう1つのアプローチは、CSSルックアップを使用することです。

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

が、そのCSS検索はCSSがシーンがためにレンダリングされた後にこの手段、デフォルトでは(適用された後までは動作しません注意してください。myFormは、すべてのテキストフィールドの祖先であるいくつかのノードである場合初めて)。すべてのテキストフィールドはすべて(例えば、最初の例ではグリッドペインのような)単一の直接の親に含まれている場合

別の方法として、子ノードを反復処理し、テキストフィールドをフィルタリングすることであろう。

textFieldParentNode.getChildrenUnmodifiable().stream() 
    .filter(TextField.class::isInstance) 
    .map(TextField.class::cast) 
    .forEach(tf -> tf.setText("Hello")); 
関連する問題