Java FX JsonObjekt Children auslesen

Dieses Thema Java FX - JsonObjekt Children auslesen im Forum "Allgemeine Java-Themen" wurde erstellt von iso66, 4. Dez. 2014.

Thema: JsonObjekt Children auslesen Hallo liebes Forum, ich hab folgenden Java Code: public void generatejson(File file, Object stage) {...

  1. Hallo liebes Forum,

    ich hab folgenden Java Code:
    Code (Java):
       
    public void generatejson(File file, Object stage) {

           
        try {
            JSONObject object = (JSONObject) new JSONParser().parse(new FileReader(file));
               
            JSONObject child = new JSONObject();
            child.get(child);
               
            for(int i=0;i<child.size(); i++){
                @SuppressWarnings("unused")
                JSONArray children= (JSONArray) child.get(i);
                System.out.println("Kind1 Children\n" + child);
            }
               
               
            } catch (Exception e) {
                e.printStackTrace();
       
            }
            // This implies that the first token in JsonToken.BEGIN_OBJECT, which is always true.
            // handleObject(reader);

        }
     
    Mein Problem ist, ich will die Kinder von dem JsonObjekt, den ich in Line 6 erstelle habe, Rekursiv und einzeln an meiner Console anzeigen lassen. Also am Anfang nur die Kinder, danach die Kindes Kinder.
    Ich glaube, dass ich ab Line 8 - 16 nicht ganz richtig ist, weil die geöffnete Json-Datei nebeneinander auf meiner Console angezeigt wird.

    Bitte um Hilfe.
     
  2. Vielleicht helfen dir diese Java-Grundlagen weiter --> *Klick*
  3. Falsches Unterforum, aber ich antworte mal trotzdem :)

    So. Also. Naja, für Rekursion brauchst du auch eine sich wieder selbst aufrufende Methode, oder? ;-)

    Erster Fehler:
    Zeile 9
    child.get(child);

    Ich denke du willst
    JSONObject child = object.getJSONObject("my-object"); // ersetze "my-object" mit einem richtigen Namen

    Frage meinerseits: Hat das Json ein festes Format? Wird es immer das Gleiche sein? Wenn ja, verwende einen Objektrelationalen Mapper wie jackson, gson oder so.
    Vorteil: Du erhälst ordentliche Java-Beans. Musst dich also nicht so "Low-Level" durch den Json-Baum hangeln.
    Nachteil: Etwas höherer Memory-Footprint (glaube ich zumindest) und "nicht so flexibel". Manchmal genügt dein Ansatz, aber ich mach das nur im "Notfall".
     
    MattElg gefällt das.
  4. Danke für deine Antwort Dzim,
    Ich hab es nun so gemacht Dzim:
    Code (Java):

    try {
                JSONObject parent = (JSONObject) new JSONParser().parse(new FileReader(file));

                // First Key zeigt die Parents an
                for (Object key : parent.keySet()) {
                    System.out.println(key);

                    JSONObject child1 = (JSONObject) parent.get(key); // Show Parent keys

                    // Second Key key2:child1 first child -->
                    for (Object key2 : child1.keySet()) {
                        System.out.println("    " + key2);

                        Object child2 = child1.get(key2); // Child 2 kommt unter child 1

    }
    }
    }
     
    So lass ich mir den Tree, schritt für schritt an der Console ausgeben, jedoch wie du gemeint hast, was fehlt ist Rekursiv Methode.

    Ich habe einen festes Format, jedoch wird es nicht immer das selbe Json-Format sein.
    Hab mir auch überlegt ob ich den Jackson Mapper nehmen soll, ist es besser?
     
  5. Besser... Darüber lässt sich streiten. Einfacher? Auf jeden Fall. Du wirst das Format nicht alle Nase lang ändern (ausser vielleicht in der Design-Phase), somit ist es langfristig einfacher. Und Im Code ist dir auch immer schneller klar, was wo und warum passiert.

    Bezüglich der Rekursion: Rekursion ist nicht, Schleifen zu schachteln! Rekursion ist, wenn sich eine Methode selbst aufruft - und idealerweise gemäss Divide & Conquer - ein Problem zerlegt und verarbeitet.

    Unfertiger Java-Pseudo-Code sähe in etwa so aus (aus dem Gedächtnis, keine Lust zu Ende zu schreiben :-D )
    [code=Java]
    private void callPrintJson(JSONObject root) {
    printJson(0, root);
    }

    private void printJson(int level, JSONObject node) {
    for (String key : node.keySet()) {
    if (value == (String||boolean||double||long||int)) { // pseudo code
    // print
    } else if (value == JSONObject) {
    printJson(level+1, value);
    } else if (value == JSONArray) {
    // iterate over values,
    // if JSONObject: printJson(level+1, value);
    }
    }
    }
    [/code]

    Etwa klar, was ich meine?
     
  6. Guten morgen Dzim ,

    hab mal ne frage wieso nimmst du in dem Code Oben printJson, hat dies einen besonderen Anlass?
     
  7. Nope. Wollte erst eine rekursive #toString-Methode machen, war mir dann abends aber doch zu viel und ich hab sie nur nicht umbenannt... :)
     
  8. Achso,ich hab wie ein verrückter im Google, danach gesucht.
    :lol:
     
  9. Guten morgen,
    ich hab folgenden Code:
    Code (Java):
    public class Convert{

    public void generatejson(File file, Object stage) {
           
           
            try {
                JSONObject parent = (JSONObject) new JSONParser().parse(new FileReader(file));
               
               
                // First Key zeigt die Parents an
                for (Object key : parent.keySet()) {
                    System.out.println(key);

                    JSONObject child1 = (JSONObject) parent.get(key); // Show Parent keys

                    // Second Key key2:child1 first child -->
                    for (Object key2 : child1.keySet()) {
                        System.out.println("    " + key2);

                        Object child2 = child1.get(key2); // Child 2 kommt unter child 1

                        // Laufzeitüberprüfung prüfung ob kombatibel ist.
                        if (child2 instanceof JSONObject) {
                            JSONObject child2a = (JSONObject) child2;
                        } else if (child2 instanceof String) {
                            System.out.println("    " + "       " + child2);
                        }
                    }

                }
    }
    }
    }
     
    Ich bekomme diesen Code, nicht Rekursive, könntet ihr mir bitte helfen bin am verzweifeln.
     
  10. Bin verwirrt: Was willst du mit dem Code erreichen? JSON generieren (Java->JSON, der Name der Methode suggeriert das), oder parsen (also JSON->Java)?
     
  11. JSON -> Java, will ich generieren.
     
  12. Dann willst du parsen, nicht generieren.

    Parsen = JSON -> Java
    Generieren = Java -> JSON

    Beispiel des Parsings mit Jackson:
    https://github.com/FasterXML/jackson

    Hier noch ein kleines Tutorial:
    How to convert Java object to / from JSON (Jackson)

    Beispiel (nutz aber noch die alte Version 1.9.11):

    Modell
    Code (Java):

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Locale;

    public class Manifest {
       
        private List<ManifestEntry> files;
       
        private String version;
        private String revision;
        private Boolean required;
        private String hash;
       
        public List<ManifestEntry> getFiles() {
            if (files == null) {
                files = new ArrayList<ManifestEntry>();
            }
            return files;
        }
       
        public String getVersion() {
            return version;
        }
       
        public void setVersion(String version) {
            this.version = version;
        }
       
        public String getRevision() {
            return revision;
        }
       
        public void setRevision(String revision) {
            this.revision = revision;
        }
       
        public Boolean getRequired() {
            return required;
        }
       
        public void setRequired(Boolean required) {
            this.required = required;
        }
       
        public String getHash() {
            return hash;
        }
       
        public void setHash(String hash) {
            this.hash = hash;
        }
    }
     
    Code (Java):

    public class ManifestEntry {
       
        private String hash;
        private String file;
        private Long size;
       
        public ManifestEntry() {}
       
        public String getHash() {
            return hash;
        }
       
        public void setHash(String hash) {
            this.hash = hash;
        }
       
        public String getFile() {
            return file;
        }
       
        public void setFile(String filename) {
            this.file = filename;
        }
       
        public Long getSize() {
            return size;
        }
       
        public void setSize(Long size) {
            this.size = size;
        }
    }
     
    Parser (nur Methoden):
    Code (Java):

        public static synchronized Manifest readManifest(File source) throws JsonParseException, JsonMappingException, FileNotFoundException, IOException {
            Manifest mf = null;
            org.codehaus.jackson.map.ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper();
            // wenn der root eine Liste ist:
            // mapper.readValue(new FileInputStream(source),mapper.getTypeFactory().constructCollectionType(List.class,ManifestEntry.class));
            // ansonsten direkt die Klasse angeben
            mf = mapper.readValue(new FileReader(source), Manifest.class);
            return mf;
        }
       
        public static synchronized void writeManifest(File target, Manifest mf) throws JsonGenerationException, JsonMappingException,
                FileNotFoundException, IOException {
            if (target == null || mf == null) {
                return;
            }
            org.codehaus.jackson.map.ObjectMapper mapper = new org.codehaus.jackson.map.ObjectMapper();
            // wenn der root eine Liste ist:
            // mapper.writeValue(new FileOutputStream(target,false),mf.getFiles());
            // ansonsten direkt die Klasse angeben
            mapper.writeValue(new FileOutputStream(target, false), mf);
        }
     
    Code (Text):

    {
      "files":[
        {"hash":"/BRhU+4aPDhUT3g6kce9hJQjFBtfElyQLNjdmTJqSmE=","file":"appFX-0.10.0.jar","size":768954},  
        {"hash":"VJitYa+NmYQnup55wTcRWhGe8Q4jqxsv4qmCLA8EMnU=","file":"libs/sqlite-jdbc-3.8.7.jar","size":3964244},  
        {"hash":"E2iUGODXO4WGW4PAOcpXCd2JRO2BFItJA1UVq71y+n0=","file":"libs/jackson-all-1.9.11.jar","size":1147899}
      ],
      "version":"0.10.0",
      "revision":"3545647",
      "required":null,
      "hash":"jP2T6k7D8c8rwpH6oeezIAGUGD+yclM4icVKUNgcxhw="
    }
     
    That's it.
     
    Zuletzt bearbeitet: 8. Dez. 2014
  13. Danke dir Dzim, schau mir das ganze mal an.
     
  14. Ich muss den Code, den ich vorhin gepostet habe rekursive schreiben Dzim, so das ich an meiner Console, mit println einen Tree Form für mich anzeigen lassen kann. Das ist mein Problem, dass ich den Code nicht rekursive bekomme.
    Parsen und das ganze funktioniert bei mir.
     
  15. Da ich nicht weiss, welche Bibliothek du nutzt: Ich habe das erste von der Liste bei json.org für Java heruntergeladen und in ein Test-Projekt geworfen:

    JSON --> https://github.com/douglascrockford/JSON-java

    Code (Java):

    import java.io.File;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.Reader;

    import org.json.JSONArray;
    import org.json.JSONObject;
    import org.json.JSONTokener;

    public class JSONRecursive {
       
        public static void main(String[] args) throws IOException {
            JSONRecursive jsonRecursive = new JSONRecursive(new File(args[0]));
            jsonRecursive.doPrint();
        }
       
        private final File f;
       
        public JSONRecursive(File f) {
            this.f = f;
        }
       
        public void doPrint() throws IOException {
            Reader reader = new FileReader(f);
            JSONTokener tokener = new JSONTokener(reader);
            JSONObject object = new JSONObject(tokener);
            StringBuilder sb = new StringBuilder();
            printJsonObject(sb, 0, object);
            System.out.println(sb.toString());
            reader.close();
        }
       
        private void printJsonObject(StringBuilder sb, int level, JSONObject jsonObject) {
            sb.append(String.format("%s{%n", intent(level)));
            String[] names = JSONObject.getNames(jsonObject);
            for (int i = 0; i < names.length; i++) {
                String name = names[i];
                sb.append(String.format("%s'%s': ", intent(level + 1), name));
                Object o = jsonObject.get(name);
                printObject(sb, level + 1, o);
                if ((i + 1) < names.length) {
                    sb.append(",");
                }
                sb.append("\n");
            }
            sb.append(String.format("%s}", intent(level)));
        }
       
        private void printObject(StringBuilder sb, int level, Object o) {
            if (o instanceof Boolean) {
                sb.append(String.format("%b", (Boolean) o));
            } else if (o instanceof Double) {
                sb.append(String.format("%f", (Double) o));
            } else if (o instanceof Integer) {
                sb.append(String.format("%d", (Integer) o));
            } else if (o instanceof Long) {
                sb.append(String.format("%d", (Long) o));
            } else if (o instanceof String) {
                sb.append(String.format("%s", (String) o));
            } else if (o instanceof JSONObject) {
                // Rekursion auf die obere Methode - weil ist einfacher so...
                printJsonObject(sb, level + 1, (JSONObject) o);
            } else if (o instanceof JSONArray) {
                // Rekursion auf diese Methode
                sb.append("[\n");
                JSONArray jsonArray = (JSONArray) o;
                for (int i = 0; i < jsonArray.length(); i++) {
                    printObject(sb, level + 1, jsonArray.get(i));
                    if ((i + 1) < jsonArray.length()) {
                        sb.append(",");
                    }
                    sb.append("\n");
                }
                sb.append(String.format("%s]", intent(level)));
            }
        }
       
        private String intent(int level) {
            if (level == 0) {
                return "";
            }
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < level; i++) {
                sb.append("  ");
            }
            return sb.toString();
        }
    }
     
    produziert JSON-Formatierten Code (nicht unbedingt sinnvoll, wenn man bereits gleich formatierten Code hat, aber über Sinn und Unsinn kann man sich streiten... :) ).

    muss im Prinzip nur minimal angepasst werden um einen Baum darzustellen. Und alles einzeln auf die Konsole werfen muss man imho nicht (daher schleife ich auch die StringBuilder-Instanz immer durch - könnte man auch durch System.out.print(), bzw. System.out.printf() ersetzt werden).
     
    Zuletzt bearbeitet: 8. Dez. 2014
  16. Danke, vielmals für deine Mühe Dzim. Du hast mich von den ganzen Kopfschmerzen erlöst.
     
  17. Was jetzt nicht heisst, dass du es nicht lernen musst, zu verstehen! Das Beispiel ist klein genug, um es jedenfalls verstehen zu lernen.

    BTW: Einige haben es in ihrer Signatur... Ich nicht. Dennoch: freu mich natürlich, wenn du an hilfreiche Posts von mir auch ein "Daumen hoch" gibst. Verbessert auch meine Statistik für Tops... :)
     
  18. Dzim in Line 36 kann er mir den jsonobject garnicht finden, bekomm da den Fehler.

    Code (Java):
    The method getNames(JSONObject) is undefined for the type JSONObject
    und wenn ich jsonObject mache bekomm ich den Fehler
    Code (Java):
    jsonObject cannot be resolved to a variable

    Kannst du mir ein Tipp geben wie ich es verbessern kann bitte.
     
  19. Du musst die richtige Bibliothek verwenden. Ich hatte es ja oben angemerkt: Ich habe die erste von der json.org-Seite verwendet:
    JSON --> https://github.com/douglascrockford/JSON-java

    Es gibt unzählige andere, die alle mehr oder weniger das gleiche machen. Diese war die erste simple, die mir untergekommen ist (und ist glaube ich auch so was wie die "offizielle", aber da hab ich keine Ahnung). Ich dieses Package nur aus Android (aber auch da ist es minimal anders).
     
    Zuletzt bearbeitet: 8. Dez. 2014
  20. hmm, komisch hab die simple packages probiert sowie auch den Android, von der Seite die du mir gepostet hast.
    Nur im Line 36 bekomme ich den Fehler, ich den mal das der Fehler generell von getNames() kommt.
     
  21. das ist eine statische Methode der Klasse JSONObject. Mehr kann ich dir darüber auch nicht sagen, ausser das die von GitHub sie eben hat. Lade doch einfach diese runter und nutze sie... Was hindert sich daran?
     
  22. Geht Deine Empfehlung auch bei anderen JavaFX Objekten, z. B. bei einem GridPane, eine Textfield setzen und davon den Namen holen?
    Oder kann man den Namen des TextFields im Controller ändern?
    @FXML private GridPane bGrid;
    int row = 1;
    private void bgrow() { // warum muss ich dies dynamisch machen, ich brauche nur je eine neue Zeile und die alten Textfelder müssen stehen bleiben
    TextField zeile = new TextField();
    buchungszeile.setEditable(true);
    String hilf2 = String.valueOf(row-1);
    zeile.setText(hilf2);
    TextField posNr = new TextField();
    TextField posNr = new TextField();
    DatePicker datum2 = new DatePicker();
    //pattern2 = Pattern.compile(regExDate);
    datum2.setPromptText(pattern.toLowerCase());
    datum2.setValue(null);
    ComboBox Nr = new ComboBox(); //muss ComboBox werden
    nr.setItems(kontNr);
    nr.setEditable(true);
    ComboBox auswahl = new ComboBox(); //muss ComboBox werden
    auswahl.setItems(kontText);
    TextField betragZeile = new TextField();
    Button weitereRow = new Button();
    weitereRow.prefWidth(180);
    weitereRow.setText("Weitere Zeile");
    weitereRow.setOnAction((EventHandler<ActionEvent>) new handleWeitereZeileEvent());
    //ab zweiter Zeile
    bGrid.addRow(row);
    bGrid.add(zeile, 0, row);
    bGrid.add(nr, 1, row);
    bGrid.add(posNr, 2, row);
    bGrid.add(datum2, 3, row);
    bGrid.add(betragZeile, 4, row);
    bGrid.add(waer, 5, row);
    bGrid.add(text, 6, row);
    bGrid.add(weitereRow, 7, row);
    row = row+1;
    // Meldung reseten
    meldungT.setText("");


    --
    Und hier springe ich nun über den Button weitereRow und das ActionEvent noch einmal in die Methode bgrow rein, erzeuge also die gesamten Textfields noch einmal. Kann sie aber nicht auslesen, weil ich in einer anderen Methode die Namen der Textfields nicht habe.
     
  23. Joose
    Joose Mitarbeiter
    Warum diesen uralt Thread ausgraben?

    Was hat JSON mit JavaFX bzw. FXML Dateien zu tun?

    Füge deine Textfields zu einer Liste hinzu, dann kannst du auch später darauf zugreifen.
     
  24. Ich fand dieses Beispiel und fand es interessant und dachte, wenn dies auch JavaFX geht, wäre es gut:
    D. h. dynamisch TextFields erzeugen und von diesen die Namen auslesen, um mit ihnen zu arbeiten.
     
  25. Joose
    Joose Mitarbeiter
    Wenn was mit JavaFX auch geht?
    Sollte jetzt auch schon auf die eine oder andere weise möglich sein ;)
     
  26. KOSTENLOSES Java-Grundlagen Training im Wert von 39 € Sichere dir hier den kostenlosen Zugriff auf umfangreiches Java-Know How und starte richtig durch!