Search code examples
javajavafxintrospection

Introspection (JavaFx)


after having made quite a lot of searches, I leave it up to you. Here is in my application JavaFx, I use the introspection to generate a gridPane automatically (that I insert then into Dialog). Thus I have TableView, when the user doubles click above, it generates Dialog containing the columns of this TableView. In this Dialog, thus there is TextFields which allow to modify the values of fields in TableView. But well, I cannot get back the value of my attributes by means of the introspection, and how make get back the value of the textFields which were created thanks to the introspection? There is my introspection method :

    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;
}

Here is the code where I call on to the method of introspection :

                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 ?????

                    }

                }

Thank in advance ;)


Solution

  • There are many ways of solving this, for example, you can use the userData property to store the key of the attributes, so you can iterate later over the GridPane children and obtain each value in the Dialog result converter.

    When you introspect the 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);
            }
    

    When you creat the 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
                }
            }
        });