可以将java.lang.reflect.Field发布到javafx.scene.control.TextField吗?
例如:
Field[] nodes;
nodes = clase.getDeclaredFields();
for (Field n : nodes)
if (n.getType().getSimpleName().equals("TextField"))
((TextField)((Object) n)).setText("Text");
答案 0 :(得分: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();
}
答案 1 :(得分:0)
反思可能是一个非常糟糕的方法。在许多问题中,您使功能依赖于代码的编写方式。具体来说,您假设每个文本字段都存储在某个类的特定实例字段中。如果您更改了实施,例如因此,您将文本字段保留在数据结构中而不是自己维护对它们的引用,那么您的功能将会中断。由于显而易见的原因,编写与代码的实际实现紧密耦合的代码是不好的做法。
一种更好的方法就是将所有文本字段放在一个列表(或其他数据结构)中,这样您就可以轻松地随意使用它们。 E.g。
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"));