自省(JavaFx)
Introspection (JavaFx)
在进行了大量搜索之后,我将其留给您。
这是在我的应用程序 JavaFx 中,我使用内省自动生成一个 gridPane(然后将其插入到 Dialog 中)。因此我有 TableView,当用户双击上面时,它会生成包含此 TableView 的列的对话框。
在此对话框中,因此存在允许修改 TableView 中字段值的 TextFields。
但是,我无法通过内省取回属性的值,如何取回由于内省而创建的 textFields 的值?
有我的自省方法:
public static GridPane analyserChamp(Etudiant etu) {
List<String> list = new ArrayList<>();
Class<? extends Etudiant> classPixel = etu.getClass();
Field attribut[] = classPixel.getDeclaredFields();
GridPane gp = new GridPane();
int i=0;
for(Field p : attribut) {
list.add(p.getName());
Label lab = new Label();
if(!p.getName().equals("classe")) {
TextField l = new TextField();
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
gp.add(lab, 0, i);
i++;
}
return gp;
}
这是我调用内省方法的代码:
if(e.getClickCount() == 2) {
Dialog<Etudiant> dialog = new Dialog<>();
Etudiant test = tableViewEtudiant.getSelectionModel().getSelectedItems().get(0);
if(test!=null) {
dialog.setTitle("Editor");
dialog.setHeaderText("You can update your question");
dialog.getDialogPane().setContent(Analysateur.analyserChamp(test));
ButtonType buttonCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
ButtonType buttonOk = new ButtonType("Ok", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(buttonOk,buttonCancel);
//Confirmation of the edition
Optional<Etudiant> result = dialog.showAndWait();
//Edition of the question in the gson file
GridPane tmp = Analysateur.analyserChamp(test);
if(result.isPresent()) {
// Here ?????
}
}
提前致谢;)
有很多方法可以解决这个问题,比如可以用userData
属性 来存储属性的key,这样以后就可以遍历GridPane
children 并获取 Dialog
结果转换器中的每个值。
当你反省 class Etudiant
:
if(!p.getName().equals("classe")) {
TextField l = new TextField();
l.setUserData(p.getName()); //Store the attribute name in the TextField
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.setUserData(p.getName()); //Store the attribute name in the ComboBox
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
当您创建 Dialog
:
Dialog<Etudiant> dialog = new Dialog<>();
...
GridPane content = Analysateur.analyserChamp(test); //Keep the content accesible
...
dialog.getDialogPane().setContent(content);
...
dialog.setResultConverter(button -> { //Convert the result
Etudiant result = new Etudiant();
for (Node child : content.getChildren()) { //Iterate over the GridPane children
if (child instanceof TextField) {
String attribute = ((TextField)child).getUserData();
String value = ((TextField)child).getTest();
//Set the value in the result attribute via instrospection
}
if (child instanceof ComboBox) {
//Do the same with combos
}
}
});
存储 Supplier
以获取 Map<Field, Supplier<?>>
中字段的输入值。这样您就可以浏览地图的条目并检索分配的值:
public class ReflectionDialog<T> extends Dialog<T> {
public ReflectionDialog(Class<T> type, Supplier<T> factory) throws IllegalAccessException {
GridPane gp = new GridPane();
Field[] fields = type.getDeclaredFields();
// stores getters for result value
final Map<Field, Supplier<?>> results = new HashMap<>();
int i = 0;
for (Field field : fields) {
if (String.class.equals(field.getType())) {
String name = field.getName();
Node input;
Supplier<?> getter;
if ("classe".equals(name)) {
ComboBox<String> cb = new ComboBox<>();
cb.getItems().addAll("1Bi", "2Bi", "3Bi");
getter = cb::getValue;
input = cb;
} else {
TextField l = new TextField();
getter = l::getText;
input = l;
}
results.put(field, getter);
gp.addRow(i, new Label(name), input);
i++;
}
}
getDialogPane().setContent(gp);
getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
setResultConverter(buttonType -> {
if (buttonType == ButtonType.OK) {
// create & initialize new object
final T object = factory.get();
results.forEach((k, v) -> {
try {
k.set(object, v.get());
} catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
});
return object;
} else {
return null;
}
});
}
}
public class A {
String classe;
String value;
@Override
public String toString() {
return "A{" + "classe=" + classe + ", value=" + value + '}';
}
}
ReflectionDialog<A> dialog = new ReflectionDialog<>(A.class, A::new);
A result = dialog.showAndWait().orElse(null);
System.out.println(result);
在进行了大量搜索之后,我将其留给您。 这是在我的应用程序 JavaFx 中,我使用内省自动生成一个 gridPane(然后将其插入到 Dialog 中)。因此我有 TableView,当用户双击上面时,它会生成包含此 TableView 的列的对话框。 在此对话框中,因此存在允许修改 TableView 中字段值的 TextFields。 但是,我无法通过内省取回属性的值,如何取回由于内省而创建的 textFields 的值? 有我的自省方法:
public static GridPane analyserChamp(Etudiant etu) {
List<String> list = new ArrayList<>();
Class<? extends Etudiant> classPixel = etu.getClass();
Field attribut[] = classPixel.getDeclaredFields();
GridPane gp = new GridPane();
int i=0;
for(Field p : attribut) {
list.add(p.getName());
Label lab = new Label();
if(!p.getName().equals("classe")) {
TextField l = new TextField();
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
gp.add(lab, 0, i);
i++;
}
return gp;
}
这是我调用内省方法的代码:
if(e.getClickCount() == 2) {
Dialog<Etudiant> dialog = new Dialog<>();
Etudiant test = tableViewEtudiant.getSelectionModel().getSelectedItems().get(0);
if(test!=null) {
dialog.setTitle("Editor");
dialog.setHeaderText("You can update your question");
dialog.getDialogPane().setContent(Analysateur.analyserChamp(test));
ButtonType buttonCancel = new ButtonType("Cancel", ButtonData.CANCEL_CLOSE);
ButtonType buttonOk = new ButtonType("Ok", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(buttonOk,buttonCancel);
//Confirmation of the edition
Optional<Etudiant> result = dialog.showAndWait();
//Edition of the question in the gson file
GridPane tmp = Analysateur.analyserChamp(test);
if(result.isPresent()) {
// Here ?????
}
}
提前致谢;)
有很多方法可以解决这个问题,比如可以用userData
属性 来存储属性的key,这样以后就可以遍历GridPane
children 并获取 Dialog
结果转换器中的每个值。
当你反省 class Etudiant
:
if(!p.getName().equals("classe")) {
TextField l = new TextField();
l.setUserData(p.getName()); //Store the attribute name in the TextField
lab.setText(p.getName());
gp.add(l, 1, i);
}else {
ComboBox<String> cb = new ComboBox<String>();
cb.setUserData(p.getName()); //Store the attribute name in the ComboBox
cb.getItems().addAll("1Bi","2Bi","3Bi");
gp.add(cb, 1, i);
}
当您创建 Dialog
:
Dialog<Etudiant> dialog = new Dialog<>();
...
GridPane content = Analysateur.analyserChamp(test); //Keep the content accesible
...
dialog.getDialogPane().setContent(content);
...
dialog.setResultConverter(button -> { //Convert the result
Etudiant result = new Etudiant();
for (Node child : content.getChildren()) { //Iterate over the GridPane children
if (child instanceof TextField) {
String attribute = ((TextField)child).getUserData();
String value = ((TextField)child).getTest();
//Set the value in the result attribute via instrospection
}
if (child instanceof ComboBox) {
//Do the same with combos
}
}
});
存储 Supplier
以获取 Map<Field, Supplier<?>>
中字段的输入值。这样您就可以浏览地图的条目并检索分配的值:
public class ReflectionDialog<T> extends Dialog<T> {
public ReflectionDialog(Class<T> type, Supplier<T> factory) throws IllegalAccessException {
GridPane gp = new GridPane();
Field[] fields = type.getDeclaredFields();
// stores getters for result value
final Map<Field, Supplier<?>> results = new HashMap<>();
int i = 0;
for (Field field : fields) {
if (String.class.equals(field.getType())) {
String name = field.getName();
Node input;
Supplier<?> getter;
if ("classe".equals(name)) {
ComboBox<String> cb = new ComboBox<>();
cb.getItems().addAll("1Bi", "2Bi", "3Bi");
getter = cb::getValue;
input = cb;
} else {
TextField l = new TextField();
getter = l::getText;
input = l;
}
results.put(field, getter);
gp.addRow(i, new Label(name), input);
i++;
}
}
getDialogPane().setContent(gp);
getDialogPane().getButtonTypes().addAll(ButtonType.OK, ButtonType.CANCEL);
setResultConverter(buttonType -> {
if (buttonType == ButtonType.OK) {
// create & initialize new object
final T object = factory.get();
results.forEach((k, v) -> {
try {
k.set(object, v.get());
} catch (IllegalAccessException ex) {
throw new IllegalStateException(ex);
}
});
return object;
} else {
return null;
}
});
}
}
public class A {
String classe;
String value;
@Override
public String toString() {
return "A{" + "classe=" + classe + ", value=" + value + '}';
}
}
ReflectionDialog<A> dialog = new ReflectionDialog<>(A.class, A::new);
A result = dialog.showAndWait().orElse(null);
System.out.println(result);