JavaFX TextArea updated nicht

MrSnake

Mitglied
Ich habe ein Tool geschrieben welches mehrere Dateien kopiert, erstellt und verändert - bisher habe ich das ganze auf Konsole ausgeben lassen...

Nun, da alles funktioniert wie gewünscht, habe ich mir eine Applikation ringsherum gebastelt mit einer TextArea wo die entsprechenden System.out.println() Meldungen in Echtzeit angezeigt werden sollen.
An den entsprechenden Stellen habe ich dann txtArea.append("Meldung") eingefügt - jedoch sehe ich keine Live Meldungen wie in der Konsole.

Erst wenn alles abgearbeitet ist erscheinen alle Meldungen auf einmal!

Wie kann ich das realisieren? repaint() oder validate() gibts es ja leider nicht....
 

thet1983

Top Contributor
Schreib dir eine Methode die die Meldung ausgibt..

Java:
public void getMeldung(String in){
   textArea.append(in+"/n");
}

Die schreibst du dann überall hin wo du sie benötigst.

Ich persönlich verwende immer eine List
 

MrSnake

Mitglied
Der Vorschlag ändert nichts am Ergebnis - der komplette Text erscheint am Ende gesammelt...

Was für ein Element ich dabei nutze, spielt für mich keine Rolle - hauptsache ich sehe die Meldungen in Echtzeit.

Kannst Du mir evtl ein Beispiel mit List zeigen von Dir?
 

MrSnake

Mitglied
Die beiden Passagen mit txtImport.appendText() in dieser Funktion zum Beispiel.
Einmal am Anfang, einmal am Ende

Java:
private void getHeroClasses() {
    txtImport.appendText("\nDaten aus dem Array HeroClasses sammeln\n");
    //alle HeroClasses durchgehen
    JSONArray arrayHeroClasses = jsonFull.getJSONArray("HeroClasses");
    for(int i = 0; i<arrayHeroClasses.length(); i++) {
        JSONObject jsonHeroClass = (JSONObject) arrayHeroClasses.get(i);
        //unnötige Werte entfernen
        jsonHeroClass.remove("Abbreviation");
        //XML Daten holen
        String name = jsonHeroClass.getString("Name");
        String nameNew = find_XML_Content(name);
        jsonHeroClass.put("Name", nameNew);
        JSONArray arrayAugmentName = jsonHeroClass.getJSONArray("AugmentName");
        for(int j=0; j<arrayAugmentName.length(); j++) {
            String augmentName = arrayAugmentName.getString(j);
            String augmentNameNew = find_XML_Content(augmentName);
            arrayAugmentName.put(j, augmentNameNew);
        }
    }
    txtImport.appendText("Anzahl HeroClasses: "+arrayHeroClasses.length()+"\n" +
            "--------------------------------------------------------------\n");
}
 

MrSnake

Mitglied
Hier mal eine genauere Abbildung der Struktur!
In so ziemlich jeder Funktion ist eine appendText() enthalten...

Java:
//Elemente
private Label lblCheckFiles = new Label("Dateiprüfung:"), lblCheckJSON = new Label("check"), lblCheckXML = new Label("check");
private TextArea txtImport = new TextArea();

//JSONObject mit komplettem Inhalt der World.json
private static JSONObject jsonFull;

@Override
public void start(Stage primaryStage) throws Exception{...}

private void importData() {
    System.out.println(saveAs.getAbsolutePath());
    convertXML();
    filterJSON();
    saveNewJSON();
}

private void convertXML() {...}

private void filterJSON() {
        getHeroClasses();
        getKingdoms();
        getSpells();
        getTraits();
        getTroops();
        getWeapons();
}

private void getHeroClasses() {...}

private void getKingdoms() {...}

private void getSpells() {...}

private void getTraits() {...}

private void getTroops() {...}

private void getWeapons() {...}

private String find_XML_Content(String searchString) {...}

private void saveNewJSON() {...}
 

thet1983

Top Contributor
Ja dann ist es e klar läuft ja alles auf einmal ab.
Ich dachte du hättest die einzelnen Methode in Events (Button. etc)
 

MrSnake

Mitglied
Es gibt nur den Start Button der alles ins Rollen bringt, und den Schließen Button zum Programm beenden.

Es muss doch eine Möglichkeit geben den Inhalt der TextArea während der Laufzeit zu füllen!?
 

MrSnake

Mitglied
Erst kommt 20 Sekunden nichts weil er alle Funktionen ausführt. Dann erscheinen alle Meldungen die er in der Zwischenzeit erzeugt hat auf einmal.
 

thet1983

Top Contributor
Java:
// Methode die für andere Threads gelockt ist.
public synchronized void machWas(){
   //....
}
 

MrSnake

Mitglied
Ich habe nun auf einer anderen Seite auf englisch gelesen dass abgeraten wird von TextArea als Log-Element - dort wird auch ListView empfohlen.

Könntest Du mir dort ein Beispiel zeigen wie Du es verwendest?
 

Kababär

Top Contributor
Hi,

dass die Textarea erst geupdatet wird, liegt daran, dass JavaFX einen eigenen Thread hat und nur dieser Thread kann auf die GUI zugreifen. Rufst du eine normale (nicht JavaFX) Methode auf, läufst du automatisch in einem anderen Thread und die GUI friert solange ein. Probiere mal eine Interaktion auszuführen in der GUI sobald deine Berechnungen gestartet sind. Du solltest eine "Not responding" Antwort von der GUI erhalten.
Um dieses Problem zu umgehen, gibt es sogenannte Threads (bzw Task und Service). Einen Thread verwendet man, wenn nur einmal etwas ausgeführt werden soll. Man legt sich einen Task an, in dem spezifiziert wird, was passieren soll wenn dieser Task aufgerufen wird (bspw über einen Thread). Beachte jedoch, dass dieser Task nur einmal als Thread aufgerufen werden kann. Ein zweiter Aufruf würde zu einem Fehler würde.
Willst du Tasks öfter ausführen, empfiehlt sich der Service. Hier kann der Task gestoppt, gestartet und neu gestartet werden.
Wichtig sind die Methoden updateMessage und updateProgress von Thread bzw concurrency, welche die GUI über den Fortschritt informiert, denn dies ist wichtig, damit die GUI nicht einfriert.
JavaFX erwartet also immer eine regelmäßige Benachrichtigung über den Fortschritt wenn diese interaktiv bleiben soll.

Ein Beispiel ist hier:
http://stackoverflow.com/questions/18597644/javafx-update-textarea
Und die Seite von Oracle wo es mehr Infos zum nachlesen gibt
https://docs.oracle.com/javafx/2/threads/jfxpub-threads.htm

Threads sind etwas schwierig, da man sich das Wissen mehr oder weniger selbst aneignen muss und hier gilt prinzipiell "Viel probieren" und "Übersicht behalten, in welchem Thread man sich gerade befindet und das die Threads sich nicht gegenseitig blocken".
Meiner Meinung nach der Inbegriff der OOP.
Da ich dann doch leider nicht so praktisch erfahren bin mit Threads, kann ich dir auch nicht eine genaue Lösung für dein Problem geben, hoffe aber dass ich dir helfen konnte.
 

dzim

Top Contributor
Fast dasselbe Problem gab es vor kurzem schon einmal. Hier der Link meiner Antwort dazu.

http://www.java-forum.org/thema/textarea-updaten-bevor-prozess-gestartet-wird.173047/#post-1090757

Wie @Kababär es schon sagt, musst du mit Threads arbeiten. Eine Service-Klasse (und der darin enthalten - und von Thread ableitende - Task) währe das Mittel deiner Wahl. Da du aber keine Fortschritt anzeigen willst, sondern deine Text-Daten anzeigen willst, kannst du statt des "updateProgress" einfach den String an die TextArea hängen.
Da nun aber der Service auf einem anderen Thread läuft, musst du dieses Update via

Platform.runLater(Runnable)


Bei dir sähe es dann etwa so aus:

Platform.runLater(() -> txtImport.appendText("bla"));
 

MrSnake

Mitglied
Ich habe jetzt die letzten Tage damit verbracht mir alles durchzulesen und habe auch einiges probiert - allerdings hat nichts funktioniert... Das Thema Threads ist wirklich nicht gerade ein Thema was man sich mal so eben selbst aneignet! Leider haben wir mit unserem Dozenten nicht wirklich über dieses Thema gesprochen, dafür haben die 6 Wochen Java/JavaFX Kurs doch nicht ausgereicht...

Falls sich also jemand erbarmt und mir dabei helfen mag - ich poste hier mal den gesamten Code den ich habe, alle mit dem Aufrufe von txtImport.appendText("Text\n"); sollen während der Laufzeit in der TextArea erscheinen. Ich kann mir natürlich denken dass viele Sachen im Code verbesserungswürdig sind - das ist bei einem Anfänger und Hobby-Coder auch sicherlich nicht verwunderlich, dafür kommentiere ich wenigstens die wichtigsten Sachen^^

Java:
package main;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.json.JSONArray;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.swing.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;

public class ImportJSON extends Application {

    //Quelldateien
//    private File sourceWorldJSON = new File("D:\\Gamez\\STEAM\\steamapps\\common\\Gems of War\\res\\Data\\World.json");
//    private File sourceWorldXML = new File("D:\\Gamez\\STEAM\\steamapps\\common\\Gems of War\\res\\Text\\en_US\\World.xml");
//    private File sourceCommonXML = new File("D:\\Gamez\\STEAM\\steamapps\\common\\Gems of War\\res\\Text\\en_US\\Common.xml");
    private File sourceWorldJSON = new File("World.json");
    private File sourceWorldXML = new File("World.xml");
    private File sourceCommonXML = new File("Common.xml");
    private Document documentWorldXML = null, documentCommonXML = null;
    private File saveAs = null;

    //Elemente
    private Button btnStart;
    private Label lblCheckFiles = new Label("Dateiprüfung:"), lblCheckJWorldSON = new Label("check"), lblCheckWorldXML = new Label("check"), lblCheckCommonXML = new Label("check");
    private TextArea txtImport = new TextArea();

    //JSONObject mit komplettem Inhalt der World.json
    private static JSONObject jsonFull, jsonData;
    private static ObservableList<String> listTypes = FXCollections.observableArrayList();

    //JSONArrays mit originalen Daten
    private static JSONArray arrayHeroClassesOriginal, arrayKingdomsOriginal, arrayTraitsOriginal, arrayTroopsOriginal, arraySpellsOriginal, arrayWeaponsOriginal;

    @Override
    public void start(Stage primaryStage) throws Exception{
        //Oberfläche erzeugen
        lblCheckFiles.setFont(Font.font("Arial", FontWeight.BOLD, 15));
        lblCheckFiles.setPadding(new Insets(0,0,10,0));
        GridPane gridLabels = new GridPane();
        gridLabels.setHgap(10);
        gridLabels.setVgap(5);
        gridLabels.setPadding(new Insets(10,0,10,20));
        gridLabels.add(lblCheckFiles,0,0,2,1);
        gridLabels.add(new Label("World.json: "),0,1);
        gridLabels.add(lblCheckJWorldSON,1,1);
        gridLabels.add(new Label("World.xml: "),0,2);
        gridLabels.add(lblCheckWorldXML,1,2);
        gridLabels.add(new Label("Common.xml: "),0,3);
        gridLabels.add(lblCheckCommonXML,1,3);
        txtImport.setPrefWidth(600);
        txtImport.setPrefHeight(500);
        VBox boxTextArea = new VBox(txtImport);
        boxTextArea.setPadding(new Insets(10));
        btnStart = new Button("Start");
        btnStart.setPrefHeight(40);
        btnStart.setPrefWidth(100);
        Button btnClose = new Button("Schließen");
        btnClose.setPrefHeight(40);
        btnClose.setPrefWidth(100);
        HBox boxButtons = new HBox(btnStart, btnClose);
        boxButtons.setAlignment(Pos.CENTER_RIGHT);
        boxButtons.setPadding(new Insets(10));
        boxButtons.setSpacing(20);
        VBox root = new VBox(gridLabels, boxTextArea, boxButtons);
        primaryStage.setTitle("Data Import");
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
        //World.json auf Existenz prüfen
        if(sourceWorldJSON.exists()) {
            lblCheckJWorldSON.setText("Datei gefunden!");
        } else {
            lblCheckJWorldSON.setText("FEHLER: Datei nicht gefunden!");
            btnStart.setDisable(true);
        }
        //World.xml auf Existenz prüfen
        if(sourceWorldXML.exists()) {
            lblCheckWorldXML.setText("Datei gefunden!");
        } else {
            lblCheckWorldXML.setText("FEHLER: Datei nicht gefunden!");
            btnStart.setDisable(true);
        }
        //Common.xml auf Existenz prüfen
        if(sourceCommonXML.exists()) {
            lblCheckCommonXML.setText("Datei gefunden!");
        } else {
            lblCheckCommonXML.setText("FEHLER: Datei nicht gefunden!");
            btnStart.setDisable(true);
        }
        //FileChooser für Pfad der neuen Datei
        FileChooser fileChooser = new FileChooser();
        fileChooser.setInitialFileName("Data.json");
        fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("JSON", "*.json"));
        //Button Actions
        btnStart.setOnAction(event -> {
            btnStart.setDisable(true);
            saveAs = fileChooser.showSaveDialog(primaryStage);
            importData();
        });
        btnClose.setOnAction(event -> System.exit(0));
    }

    private void importData() {
        System.out.println("Speicherort --> "+saveAs.getAbsolutePath()+"\n");
        //XML Dateien umwandeln ("&" in "&amp;" wandeln)
        txtImport.appendText("Temporäre XML Dateien erzeugen\n");
        File tempWorldXML = createTempXML(sourceWorldXML);
        documentWorldXML = convertXML(tempWorldXML);
        File tempCommonXML = createTempXML(sourceCommonXML);
        documentCommonXML = convertXML(tempCommonXML);
        //JSON Daten verarbeiten
        try {
            txtImport.appendText("JSON Quelldatei einlesen und JSONObject erstellen\n");
            FileReader fileReader = new FileReader(sourceWorldJSON);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String fileContent = bufferedReader.readLine();
            bufferedReader.close();
            jsonFull = new JSONObject(fileContent);
            //Arrays aus bestehender JSON erstellen
            arrayHeroClassesOriginal = jsonFull.getJSONArray("HeroClasses");
            arrayKingdomsOriginal = jsonFull.getJSONArray("Kingdoms");
            arrayTraitsOriginal = jsonFull.getJSONArray("Traits");
            arrayTroopsOriginal = jsonFull.getJSONArray("Troops");
            arraySpellsOriginal = jsonFull.getJSONArray("Spells");
            arrayWeaponsOriginal = jsonFull.getJSONArray("Weapons");
            //Neue Arrays mit benötigten Daten füllen
            JSONObject newHeroClasses = createHeroClasses(arrayHeroClassesOriginal);
            JSONObject newKingdoms = createKingdoms(arrayKingdomsOriginal);
            JSONObject newTraits = createTraits(arrayTraitsOriginal);
            JSONObject newTroops = createTroops(arrayTroopsOriginal);
            JSONObject newSpells = createSpells(arraySpellsOriginal);
            JSONObject newWeapons = createWeapons(arrayWeaponsOriginal);
            //Object für ManaBonus erzeugen
            JSONObject manaBonus = new JSONObject();
            for(int colorNr=0; colorNr<=5; colorNr++) {
                String colorName="", searchBonus, searchDescription;
                switch(colorNr) {
                    case 0:
                        colorName = "Blue";
                        break;
                    case 1:
                        colorName = "Green";
                        break;
                    case 2:
                        colorName = "Red";
                        break;
                    case 3:
                        colorName = "Yellow";
                        break;
                    case 4:
                        colorName = "Purple";
                        break;
                    case 5:
                        colorName = "Brown";
                        break;
                }
                searchBonus = "[BONUS_COLOR_"+colorNr+"]";
                searchDescription = "[BONUS_COLOR_DESCRIPTION_"+colorNr+"]";
                manaBonus.put("Bonus"+colorName, findXMLContent(searchBonus, documentCommonXML));
                manaBonus.put("Bonus"+colorName+"Description", findXMLContent(searchDescription, documentCommonXML));
            }
            //Object für TypeBonus erzeugen
            JSONObject typeBonus = new JSONObject();
            for(String type : listTypes) {
                String typeUC = type.toUpperCase();
                String searchBonus, searchDescription;
                for(int a=3; a<=4; a++) {
                    searchBonus = "[BONUS_TROOPTYPE_"+typeUC+"_"+a+"]";
                    searchDescription ="[BONUS_TROOPTYPE_DESCRIPTION_"+typeUC+"_"+a+"]";
                    typeBonus.put(type+"_"+a, findXMLContent(searchBonus, documentCommonXML));
                    typeBonus.put(type+"_"+a+"_"+"Description", findXMLContent(searchDescription, documentCommonXML));
                }
            }
            //Neues Object für alle gesammelten Daten erstellen
            jsonData = new JSONObject();
            jsonData.put("HeroClasses", newHeroClasses);
            jsonData.put("Kingdoms", newKingdoms);
            jsonData.put("Traits", newTraits);
            jsonData.put("Troops", newTroops);
            jsonData.put("Spells", newSpells);
            jsonData.put("Weapons", newWeapons);
            jsonData.put("ManaBonus",manaBonus);
            jsonData.put("TypeBonus", typeBonus);
        } catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(null, "Datei konnte nicht gefunden werden:\n" + e.toString(), "Datei nicht gefunden", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //Data.json mit gesammelten Daten erzeugen
        saveNewJSON(jsonData.toString());
        //Temporäre XML Dateien wieder löschen
        if(tempWorldXML.delete()) {
            System.out.println("tempWorld.xml gelöscht");
            txtImport.appendText("tempWorld.xml gelöscht\n");
        }
        if(tempCommonXML.delete()) {
            System.out.println("tempCommon.xml gelöscht");
            txtImport.appendText("tempCommon.xml gelöscht\n");
        }
        saveStatistic("-----------------------------------------------------------");
        btnStart.setDisable(false);
    }

    private File createTempXML(File file) {
        //XML einlesen - "&" durch "&amp;" ersetzen
        System.out.println(file+" wird temporär neu erstellt");
        String fileContent = "", line;
        try {
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            while((line = bufferedReader.readLine()) != null) {
                line = line.replace("&", "&amp;");
                fileContent += line+"\n";
            }
            bufferedReader.close();
        } catch (FileNotFoundException e) {
            JOptionPane.showMessageDialog(null, "Datei konnte nicht gefunden werden:\n" + e.toString(), "Datei nicht gefunden", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //Temporäre XML-Datei erzeugen
        File tempXML = null;
        if(file.equals(sourceWorldXML)) {
            tempXML = new File("tempWorld.xml");
        }
        if(file.equals(sourceCommonXML)) {
            tempXML = new File("tempCommon.xml");
        }
        if(tempXML != null) {
            try {
                FileWriter fw = new FileWriter(tempXML);
                BufferedWriter bw = new BufferedWriter(fw);
                bw.write(fileContent);
                bw.close();
                System.out.println("Temporäre Datei \""+tempXML+"\" erstellt!\n");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return tempXML;
    }

    private Document convertXML(File tempXML) {
        //tempXML parsen
        Document documentXML = null;
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            documentXML = builder.parse(tempXML);
        } catch (SAXException | ParserConfigurationException | IOException e) {
            e.printStackTrace();
        }
        return documentXML;
    }

    private JSONObject createHeroClasses(JSONArray originalHeroClasses) {
        JSONObject objectHeroClasses = new JSONObject();
        for(int classNr=0; classNr<originalHeroClasses.length(); classNr++) {
            JSONObject heroClassOriginal = (JSONObject) originalHeroClasses.get(classNr);
            JSONObject heroClassNew = new JSONObject();
            //Name
            String className = findXMLContent(heroClassOriginal.getString("Name"), documentWorldXML);
            heroClassNew.put("Name", className);
            //Augments
            JSONArray arrayClassAugments = heroClassOriginal.getJSONArray("Augment");
            String augment_1 = arrayClassAugments.getString(0);
            String augment_2 = arrayClassAugments.getString(1);
            String augment_3 = arrayClassAugments.getString(2);
            heroClassNew.put("Augment_1", augment_1);
            heroClassNew.put("Augment_2", augment_2);
            heroClassNew.put("Augment_3", augment_3);
            JSONArray arrayClassAugmentNames = heroClassOriginal.getJSONArray("AugmentName");
            String augmentName_1 = findXMLContent(arrayClassAugmentNames.getString(0), documentWorldXML);
            String augmentName_2 = findXMLContent(arrayClassAugmentNames.getString(1), documentWorldXML);
            String augmentName_3 = findXMLContent(arrayClassAugmentNames.getString(2), documentWorldXML);
            heroClassNew.put("AugmentName_1", augmentName_1);
            heroClassNew.put("AugmentName_2", augmentName_2);
            heroClassNew.put("AugmentName_3", augmentName_3);
            //Traits
            JSONArray arrayClassTraits = heroClassOriginal.getJSONArray("Traits");
            String trait_1 = getTraitName(arrayClassTraits.getString(0));
            String trait_2 = getTraitName(arrayClassTraits.getString(1));
            String trait_3 = getTraitName(arrayClassTraits.getString(2));
            heroClassNew.put("Trait_1", trait_1);
            heroClassNew.put("Trait_2", trait_2);
            heroClassNew.put("Trait_3", trait_3);
            objectHeroClasses.put(className, heroClassNew);
            System.out.println("HeroClass: "+className);
        }
        txtImport.appendText("HeroClasses: "+objectHeroClasses.length()+"\n\n");
        saveStatistic("HeroClasses: "+objectHeroClasses.length());
        System.out.println("HeroClasses: "+objectHeroClasses.length());
        return objectHeroClasses;
    }

    private JSONObject createKingdoms(JSONArray originalKingdoms) {
        JSONObject objectKingdoms = new JSONObject();
        for(int kingdomNr=0; kingdomNr<originalKingdoms.length(); kingdomNr++) {
            JSONObject kingdomOriginal = (JSONObject) originalKingdoms.get(kingdomNr);
            JSONObject kingdomNew = new JSONObject();
            if(kingdomOriginal.getBoolean("Tutorial")) { //Tutorial Broken Spire filtern
                continue;
            }
            //Name
            String kingdomName = findXMLContent(kingdomOriginal.getString("Name"), documentWorldXML);
            kingdomNew.put("Name", kingdomName);
            //Banner
            String bannerName = findXMLContent(kingdomOriginal.getString("BannerName"), documentWorldXML);
            String bannerDesc = findXMLContent(kingdomOriginal.getString("BannerManaDescription"), documentWorldXML);
            kingdomNew.put("BannerName", bannerName);
            kingdomNew.put("BannerDescription", bannerDesc);
            //Einheiten
            JSONArray arrayTroopIds = kingdomOriginal.getJSONArray("TroopIds");
            JSONArray arrayTroopNames = getTroopNames(arrayTroopIds);
            kingdomNew.put("Troops", arrayTroopNames);
            //Bonus
            for(int i=2; i<5; i++) {
                int id = kingdomOriginal.getInt("Id");
                String bonusCode = "[BONUS_KINGDOM_"+id+"_"+i+"]";
                String bonus = findXMLContent(bonusCode, documentCommonXML);
                kingdomNew.put("Bonus_"+i, bonus);
                String bonusDescCode = "[BONUS_KINGDOM_DESCRIPTION_"+id+"_"+i+"]";
                String bonusDesc = findXMLContent(bonusDescCode, documentCommonXML);
                kingdomNew.put("Bonus_"+i+"_Description", bonusDesc);
            }
            //FileBase
            String fileBase = kingdomOriginal.getString("FileBase");
            kingdomNew.put("FileBase", fileBase);
            objectKingdoms.put(kingdomName, kingdomNew);
            if(kingdomOriginal.getBoolean("Used")) {
                System.out.println("Kingdom: "+kingdomName);
            } else {
                txtImport.appendText("Kingdom: "+kingdomName+" (Ungenutzt)\n");
                saveStatistic("Kingdom: "+kingdomName+" (Ungenutzt)");
                System.out.println("Kingdom: "+kingdomName+" (Ungenutzt)");
            }
        }
        txtImport.appendText("Kingdoms: "+objectKingdoms.length()+"\n\n");
        saveStatistic("Kingdoms: "+objectKingdoms.length());
        System.out.println("Kingdoms: "+objectKingdoms.length());
        return objectKingdoms;
    }

    private JSONObject createTraits(JSONArray originalTraits) {
        JSONObject objectTraits = new JSONObject();
        for(int traitNr=0; traitNr<originalTraits.length(); traitNr++) {
            JSONObject traitOriginal = (JSONObject) originalTraits.get(traitNr);
            JSONObject traitNew = new JSONObject();
            //Name
            String traitName = findXMLContent(traitOriginal.getString("Name"), documentWorldXML);
            traitNew.put("Name", traitName);
            //Beschreibung
            String traitDesc = findXMLContent(traitOriginal.getString("Description"), documentWorldXML);
            traitNew.put("Description", traitDesc);
            objectTraits.put(traitName, traitNew);
            System.out.println("Trait: "+traitName);
        }
        txtImport.appendText("Traits: "+objectTraits.length()+"\n\n");
        saveStatistic("Traits: "+objectTraits.length());
        System.out.println("Traits: "+objectTraits.length());
        return objectTraits;
    }

    private JSONObject createTroops(JSONArray originalTroops) {
        JSONObject objectTroops = new JSONObject();
        for(int troopNr = 0; troopNr< originalTroops.length(); troopNr++) {
            JSONObject troopOriginal = (JSONObject) originalTroops.get(troopNr);
            JSONObject troopNew = new JSONObject();
            if(troopOriginal.getInt("Id") == 6127) { //MegaGorgotha filtern
                continue;
            }
            //Name
            String troopName = findXMLContent(troopOriginal.getString("Name"), documentWorldXML);
            troopNew.put("Name", troopName);
            //Typ
            String typ = troopOriginal.getString("TroopType");
            troopNew.put("Typ", typ);
            //Rarity
            String rarity = getRarity(troopOriginal.getString("TroopRarity"));
            troopNew.put("Rarity", rarity);
            //Kingdom / used?
            int id = troopOriginal.getInt("Id");
            boolean used = false;
            for(int i=0; i<arrayKingdomsOriginal.length(); i++) {
                JSONObject kingdom = arrayKingdomsOriginal.getJSONObject(i);
                JSONArray troopIds = kingdom.getJSONArray("TroopIds");
                for(int j=0; j<troopIds.length(); j++) {
                    if(troopIds.getInt(j) == id) {
                        used = true;
                        String kingdomName = findXMLContent(kingdom.getString("Name"), documentWorldXML);
                        troopNew.put("Kingdom", kingdomName);
                        break;
                    }
                }
                if(used) {
                    break;
                }
            }
            //Manafarben
            JSONObject manaColors = troopOriginal.getJSONObject("ManaColors");
            troopNew.put("PrimaryColor", troopOriginal.getString("PrimaryColor"));
            troopNew.put("ManaColors", manaColors);
            //Zauber / Kosten
            int spellId = troopOriginal.getInt("SpellId");
            for(int i=0; i<arraySpellsOriginal.length(); i++) {
                JSONObject spell = arraySpellsOriginal.getJSONObject(i);
                if(spell.getInt("Id") == spellId) {
                    String spellName = findXMLContent(spell.getString("Name"), documentWorldXML);
                    troopNew.put("Spell", spellName);
                    troopNew.put("Cost", spell.getInt("Cost"));
                    break;
                }
            }
            //Traits
            JSONArray arrayTroopTraits = troopOriginal.getJSONArray("Traits");
            String trait_1 = getTraitName(arrayTroopTraits.getString(0));
            String trait_2 = getTraitName(arrayTroopTraits.getString(1));
            String trait_3 = getTraitName(arrayTroopTraits.getString(2));
            troopNew.put("Trait_1", trait_1);
            troopNew.put("Trait_2", trait_2);
            troopNew.put("Trait_3", trait_3);
            //Beschreibung
            String description = findXMLContent(troopOriginal.getString("Description"), documentWorldXML);
            troopNew.put("Description", description);
            //FileBase
            String fileBase = troopOriginal.getString("FileBase");
            troopNew.put("FileBase", fileBase);
            //Level Stats
            JSONArray healthIncrease = troopOriginal.getJSONArray("HealthIncrease");
            JSONArray armorIncrease = troopOriginal.getJSONArray("ArmorIncrease");
            JSONArray attackIncrease = troopOriginal.getJSONArray("AttackIncrease");
            JSONArray spellpowerIncrease = troopOriginal.getJSONArray("SpellPowerIncrease");
            int baseHealth = troopOriginal.getInt("Health_Base");
            int baseArmor = troopOriginal.getInt("Armor_Base");
            int baseAttack = troopOriginal.getInt("Attack_Base");
            int baseSpellpower = troopOriginal.getInt("SpellPower_Base");
            JSONArray healthLevel = calculateLevelStats(baseHealth, healthIncrease);
            troopNew.put("HealthPerLevel", healthLevel);
            JSONArray armorLevel = calculateLevelStats(baseArmor, armorIncrease);
            troopNew.put("ArmorPerLevel", armorLevel);
            JSONArray attackLevel = calculateLevelStats(baseAttack, attackIncrease);
            troopNew.put("AttackPerLevel", attackLevel);
            JSONArray magicLevel = calculateLevelStats(baseSpellpower, spellpowerIncrease);
            troopNew.put("MagicPerLevel", magicLevel);
            //Liste für alle Typen zur Kontrolle
            if(!listTypes.contains(troopOriginal.getString("TroopType"))) {
                listTypes.add(troopOriginal.getString("TroopType"));
            }
            if(used) {
                System.out.println("Troop: "+troopName);
            } else {
                txtImport.appendText("Troop: "+troopName+" (Ungenutzt)\n");
                saveStatistic("Troop: "+troopName+" (Ungenutzt)");
                System.out.println("Troop: "+troopName+" (Ungenutzt)");
            }
            objectTroops.put(troopName, troopNew);
        }
        txtImport.appendText("Troops: "+objectTroops.length()+"\n\n");
        saveStatistic("Troops: "+objectTroops.length());
        System.out.println("Troops: "+objectTroops.length());
        return objectTroops;
    }

    private JSONObject createSpells(JSONArray originalSpells) {
        JSONObject objectSpells = new JSONObject();
        for(int spellNr=0; spellNr<originalSpells.length(); spellNr++) {
            JSONObject spellOriginal = (JSONObject) originalSpells.get(spellNr);
            JSONObject spellNew = new JSONObject();
            //Name
            String spellName = findXMLContent(spellOriginal.getString("Name"), documentWorldXML);
            spellNew.put("Name", spellName);
            //Beschreibung
            String traitDesc = findXMLContent(spellOriginal.getString("Description"), documentWorldXML);
            spellNew.put("Description", traitDesc);
            objectSpells.put(spellName, spellNew);
            System.out.println("Trait: "+spellName);
        }
        txtImport.appendText("Traits: "+objectSpells.length()+"\n\n");
        saveStatistic("Traits: "+objectSpells.length());
        System.out.println("Traits: "+objectSpells.length());
        return objectSpells;
    }

    private JSONObject createWeapons(JSONArray originalWeapons) {
        JSONObject objectWeapons = new JSONObject();
        for(int weaponNr=0; weaponNr<originalWeapons.length(); weaponNr++) {
            JSONObject weaponOriginal = (JSONObject) originalWeapons.get(weaponNr);
            JSONObject weaponNew = new JSONObject();
            //Name
            String weaponName = findXMLContent(weaponOriginal.getString("Name"), documentWorldXML);
            weaponNew.put("Name", weaponName);
            //Rarity
            String rarity = getRarity(weaponOriginal.getString("WeaponRarity"));
            weaponNew.put("Rarity", rarity);
            //Mana Colors
            JSONObject manaColors = weaponOriginal.getJSONObject("ManaColors");
            weaponNew.put("ManaColors", manaColors);
            //FileBase
            String fileBase = weaponOriginal.getString("FileBase");
            weaponNew.put("FileBase", fileBase);

            objectWeapons.put(weaponName, weaponNew);
            System.out.println("Weapon: "+weaponName);
        }
        txtImport.appendText("Weapons: "+objectWeapons.length()+"\n\n");
        saveStatistic("Weapons: "+objectWeapons.length());
        System.out.println("Weapons: "+objectWeapons.length());
        return objectWeapons;
    }

    private String getRarity(String replace) {
        switch(replace) {
            case "Uncommon":
                return "Rare";
            case "Rare":
                return "UltraRare";
            case "UltraRare":
                return "Epic";
            case "Epic":
                return "Legendary";
            case "Legendary":
                return "Mythic";
            default:
                return "----";
        }
    }

    private JSONArray getTroopNames(JSONArray troopIds) {
        JSONArray troopNames = new JSONArray();
        for(int i=0; i<troopIds.length(); i++) {
            int id = troopIds.getInt(i);
            for(int j=0; j<arrayTroopsOriginal.length(); j++) {
                JSONObject troop = arrayTroopsOriginal.getJSONObject(j);
                if(troop.getInt("Id") == id) {
                    String troopName = findXMLContent(troop.getString("Name"), documentWorldXML);
                    troopNames.put(i, troopName);
                    break;
                }
            }
        }
        return troopNames;
    }

    private String getTraitName(String code) {
        String traitName = "----";
        for(int i=0; i<arrayTraitsOriginal.length(); i++) {
            JSONObject trait = arrayTraitsOriginal.getJSONObject(i);
            if(trait.getString("Code").equals(code)) {
                String trait1Code = trait.getString("Name");
                traitName = findXMLContent(trait1Code, documentWorldXML);
                return traitName;
            }
        }
        return traitName;
    }

    private JSONArray calculateLevelStats(int base, JSONArray increase) {
        JSONArray levelUp = new JSONArray();
        for(int i=0; i<increase.length(); i++) {
            if(i == 0) {
                levelUp.put(i, base+increase.getInt(i));
            } else {
                levelUp.put(i, levelUp.getInt(i-1)+increase.getInt(i));
            }
        }
        return levelUp;
    }

    private String findXMLContent(String searchString, Document documentXML) {
        String foundString;
        NodeList childList = documentXML.getElementsByTagName("Text");
        int length = childList.getLength();
        for(int i=0; i<length; i++) {
            if(childList.item(i).getAttributes().getLength() == 1) {
                NamedNodeMap nodemap = childList.item(i).getAttributes();
                if(nodemap.getNamedItem("tag").getTextContent().equals(searchString)) {
                    foundString = childList.item(i).getTextContent();
                    //System.out.println(searchString+" >>> "+foundString);
                    return foundString;
                }
            }
        }
        return searchString;
    }
    
    private void saveNewJSON(String jsonNew) {
        try {
            FileWriter fw = new FileWriter(saveAs);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(jsonNew);
            bw.close();
            System.out.println("Neue Datei \""+saveAs+"\" erstellt!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void saveStatistic(String save) {
        try {
            FileWriter fw = new FileWriter(new File("statistic.txt"), true);
            BufferedWriter bw = new BufferedWriter(fw);
            bw.append(save).append("\n");
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Wäre toll wenn sich das mal jemand anschaut - ansonsten muss ich eben damit leben...
 

Kababär

Top Contributor
Was mir auffällt ist, dass deine Klasse viel zu überdimensioniert ist. Ich kann mir vorstellen, dass ihr in JavaFX schon das MVC-Pattern kennengelernt habt, danach würde ich mich auch richten.
Wenn dein Programm nach diesem Pattern strukturiert wäre, könnte man sich auf die Funktionalität des Programms beschränken und hätte einen besseren Überblick, wo die Kommunikation zwischen GUI und dem Controller (Steuerung der GUI) stattfindet. Denn dieser Code ist mir ehrlich gesagt etwas zu lang, um eben mal drüber zu fliegen und Korrekturen durchzuführen..

Threads werdet ihr in Java/JavaFX nicht mal erwähnen. Threads sind so komplex und umfangreich, dass sie eigene Bücher füllen. Demnach gibt es dafür eigene Veranstaltungen/Module wie beispielsweise Parallele Programmierung.
 

MrSnake

Mitglied
Um ehrlich zu sein haben wir MVC nicht wirklich besprochen (oder besser gesagt nur einen tag mal angerissen), aber ich setz mich mal hin und lese etwas mehr zu diesem Thema!
 

Kababär

Top Contributor
Ist im Prinzip nicht schwer: MVC bedeutet Model-Controller-View.
Dein Model beinhaltet so ziemlich alle Variablen, ist sozusagen dein Container für alle Variablen. Durch Setter und Getter kannst du auf diese Variablen zugreifen.
Im Controller wird die Logik und das Verhalten der GUI implementiert und das V steht für View, also die GUI.
Hier wird die GUI initialisiert und leichte Änderungen der GUI können hier erfolgen. Manchmal ist allerdings nicht so recht eindeutig, ob nun eine Funktion A in die View oder den Controller gehören soll.
Dieses Pattern ist recht einfach, gerade bei JavaFX, da JavaFX auf dieses Pattern ausgelegt ist.

Einfach mal google. Beispiel:
http://blog.axxg.de/model-view-controller-mit-javafx/
 

dzim

Top Contributor
Ist auf jeden Fall ein interessanter Ausflug in die Vergangenheit der GUI-Programmierung. :) Was jetzt nicht abwertend gemeint ist, denn für @MrSnake wird es am Besten sein, damit anzufangen.
Also. @MrSnake - wenn du das verstanden hast und dein Code entsprechend aufgebaut ist, dann kannst du im nächsten Schritt dich an deklarative GUIs (hier bei JavaFX mit FXML) heranwagen, solange aber solltest du erst einmal dem Beispiel von @Kababär folgen und deinen Code entsprechend aufräumen.
Und bitte auch die ganzen, nicht mehr gebrauchten, Kommentare etc. rauswerfen (bzw. den auskommentierten Code). Wenn du ihn nicht brauchst, dann weg damit.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
K JavaFX: TextArea updated nicht AWT, Swing, JavaFX & SWT 7
L TextArea Zeichenabstand gleich machen AWT, Swing, JavaFX & SWT 8
ProggersWorld JavaFX TextArea BackgroundImage wird nicht angezeigt AWT, Swing, JavaFX & SWT 3
K Textarea aktuallisiert sich nicht, nach Auswahl (Itemlistener) AWT, Swing, JavaFX & SWT 3
D JavaFX TextArea Probleme bei langen Zeilen AWT, Swing, JavaFX & SWT 1
D Hohe Prozessorauslastung bei Ausgabe auf TextArea AWT, Swing, JavaFX & SWT 2
N Einer TextArea ein ScrollPane hinzufügen AWT, Swing, JavaFX & SWT 8
N Textdatei GUI, Text in Textarea anzeigen mehrere Zeilen AWT, Swing, JavaFX & SWT 1
Hatsi09 TextArea formattieren AWT, Swing, JavaFX & SWT 4
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
E Eingabe von Zahlen in TextArea AWT, Swing, JavaFX & SWT 2
M JavaFX TextArea disabled - ScrollBar enabled AWT, Swing, JavaFX & SWT 3
G Probleme mit TextArea AWT, Swing, JavaFX & SWT 5
R Java FX - Fxml - relative Größenangaben für Breite und Höhe einer TextArea AWT, Swing, JavaFX & SWT 8
R Swing Durch JComboBox-Item eine TextArea aktualisieren AWT, Swing, JavaFX & SWT 2
N JavaFX TextArea Updaten bevor Prozess gestartet wird AWT, Swing, JavaFX & SWT 7
B Java FX FXML Textarea SceneBuilder als XML Editor AWT, Swing, JavaFX & SWT 1
T JavaFX System.out.println in TextArea AWT, Swing, JavaFX & SWT 15
F JavaFX JavaFX HTMLEditor-Eingabe in Textarea als HTML anzeigen AWT, Swing, JavaFX & SWT 2
E To get a color text on the TextArea AWT, Swing, JavaFX & SWT 4
E To get color text on the TextArea AWT, Swing, JavaFX & SWT 5
S passende PaintComponent ? Zeichnen in TextArea mit Scrollpane ? AWT, Swing, JavaFX & SWT 2
E Swing Error icon in der TextArea AWT, Swing, JavaFX & SWT 1
thobren JavaFX textarea nach setPrefRowCount Ansicht aktualisieren AWT, Swing, JavaFX & SWT 1
thobren JavaFX Inhalte aus dynamischen vbox mit TextArea auslesen AWT, Swing, JavaFX & SWT 9
thobren Swing Im JPanel wird nur TextArea gelöscht AWT, Swing, JavaFX & SWT 13
J JavaFX TextArea dynamisch Icon im Background anzeigen AWT, Swing, JavaFX & SWT 2
M JavaFX TextArea einzelne Buchstaben färben AWT, Swing, JavaFX & SWT 3
M JavaFX TextArea richtig formatieren AWT, Swing, JavaFX & SWT 4
S ScrollPane in Textarea und auf Panel AWT, Swing, JavaFX & SWT 4
S Die Rücktaste und Entfernen in einer Textarea blockieren AWT, Swing, JavaFX & SWT 3
S TextArea get Selected row(Text) AWT, Swing, JavaFX & SWT 6
F textarea lässt panel verschwinden AWT, Swing, JavaFX & SWT 4
V Swing Update Textarea AWT, Swing, JavaFX & SWT 2
E TextArea - Maximale Zeichenanzahl AWT, Swing, JavaFX & SWT 2
N Swing teilstring in textarea fett machen AWT, Swing, JavaFX & SWT 13
J Swing TextArea mit nicht-editierbarem Text AWT, Swing, JavaFX & SWT 7
W Vergleich zweier Strings und schreiben in Textarea AWT, Swing, JavaFX & SWT 12
R AWT TextArea schreibunfähig machen AWT, Swing, JavaFX & SWT 5
J Werkzeugleiste für TextArea? AWT, Swing, JavaFX & SWT 10
M TextArea über mehrere Zeilen - wie Zeileanzahl abfragen? AWT, Swing, JavaFX & SWT 5
S Textarea und Enter AWT, Swing, JavaFX & SWT 5
El_Lobo Swing Swing TextArea und JTextField werden nicht aktualisiert AWT, Swing, JavaFX & SWT 2
R Textarea zeigt Text nicht an AWT, Swing, JavaFX & SWT 5
H TextArea zeigt kein Text an AWT, Swing, JavaFX & SWT 6
S Frage zu TextArea AWT, Swing, JavaFX & SWT 2
C TextArea Ausgabe immer ganz oben AWT, Swing, JavaFX & SWT 3
C Konsolenausgabe in TextArea ausgeben AWT, Swing, JavaFX & SWT 8
P Swing Methodenaufruf beeinflusst TextArea nicht. AWT, Swing, JavaFX & SWT 6
S TextArea ausgabe ohne JFrame zu implementieren AWT, Swing, JavaFX & SWT 2
M Swing Eine andere Klasse über Button starten und in TextArea ausgeben AWT, Swing, JavaFX & SWT 13
M Inhalt aus TextArea verarbeiten AWT, Swing, JavaFX & SWT 4
A Swing Text von System.out.printIn in eine TextArea übergen AWT, Swing, JavaFX & SWT 12
S Sobald ich TextArea mit Text fülle alles weg? AWT, Swing, JavaFX & SWT 5
P TextArea Größenänderung AWT, Swing, JavaFX & SWT 4
M problem mit keylistener/textarea AWT, Swing, JavaFX & SWT 6
H anderes font in textarea AWT, Swing, JavaFX & SWT 2
E Datei in TextArea anzeigen AWT, Swing, JavaFX & SWT 12
Luy Per TAB-Taste aus TextArea wieder raus? AWT, Swing, JavaFX & SWT 5
H AWT TextArea, TextListener AWT, Swing, JavaFX & SWT 5
D Swing [BoxLayout] Nur TextArea und nicht TextField vergroessen AWT, Swing, JavaFX & SWT 2
W JTextArea/TextArea kriegt keinen Fokus AWT, Swing, JavaFX & SWT 6
A Strings an Textarea anderer Klasse append(en) AWT, Swing, JavaFX & SWT 12
U Problem mit dem TextArea.appen()- Befehl AWT, Swing, JavaFX & SWT 2
G Textarea zeigt Text erst am Schluss an AWT, Swing, JavaFX & SWT 2
W JTextArea vs TextArea AWT, Swing, JavaFX & SWT 3
K TextArea auf Scrollpane AWT, Swing, JavaFX & SWT 3
A Dateien in TextArea ausgeben AWT, Swing, JavaFX & SWT 6
G Textarea soll automatisch mitrollen AWT, Swing, JavaFX & SWT 2
G Feste Größe einer TextArea AWT, Swing, JavaFX & SWT 2
G Kontextmenü zum kkopieren in einer TextArea AWT, Swing, JavaFX & SWT 5
D GUI + TextArea + inhalt der wörter zählen AWT, Swing, JavaFX & SWT 4
V Hilfe :( bekomme textarea nicht versetzt AWT, Swing, JavaFX & SWT 2
M TextArea relativ zur Fenstergröße AWT, Swing, JavaFX & SWT 14
Y Zahlen aus einer Textarea auslesen AWT, Swing, JavaFX & SWT 2
V textarea Problem Positionierung AWT, Swing, JavaFX & SWT 2
G textarea.read funzt net in Jar-Datei AWT, Swing, JavaFX & SWT 7
K Center Text in TextArea AWT, Swing, JavaFX & SWT 8
ModellbahnerTT Ersatz für Textarea AWT, Swing, JavaFX & SWT 13
K Zeilen von TextArea auswählen AWT, Swing, JavaFX & SWT 3
C TextArea Problem :( TextArea über komplettem JFrame AWT, Swing, JavaFX & SWT 2
S Text in Textarea über empfangenen Socketstream anzeigen AWT, Swing, JavaFX & SWT 4
M Problem mit Layout wegen Textarea AWT, Swing, JavaFX & SWT 3
F Scrollpane scrollt immer zur TextArea AWT, Swing, JavaFX & SWT 8
F Graphics2D scale und Positionierung einer TextArea AWT, Swing, JavaFX & SWT 8
J TextArea unkontrollierbar AWT, Swing, JavaFX & SWT 4
G toString -> TextArea AWT, Swing, JavaFX & SWT 2
F Einlesen von text in textArea mittels for-schleife AWT, Swing, JavaFX & SWT 3
L TextArea AWT, Swing, JavaFX & SWT 6
X textarea updaten bevor eine Methode aufegerufen wird AWT, Swing, JavaFX & SWT 6
G keyListener & textarea AWT, Swing, JavaFX & SWT 2
C Text in TextArea gestalten AWT, Swing, JavaFX & SWT 2
M Farben im TextArea AWT, Swing, JavaFX & SWT 5
N TextArea positionieren AWT, Swing, JavaFX & SWT 3
P TextArea zeilenumbruch AWT, Swing, JavaFX & SWT 7
André B. formatierung in TextArea AWT, Swing, JavaFX & SWT 7
C Textarea kontinuerlich updaten AWT, Swing, JavaFX & SWT 3
D setCaretPosition, nicht-editierbare TextArea AWT, Swing, JavaFX & SWT 8
J TextArea begrenzen AWT, Swing, JavaFX & SWT 6
P [TextArea] Text Formatieren AWT, Swing, JavaFX & SWT 4

Ähnliche Java Themen

Neue Themen


Oben