# Von JavaFx zu Android



## spike86 (25. Mai 2020)

Hallo Leute,

zuerst muss ich betonen, dass ich Java\JavaFx anfänger bin, also bitte verurteilt mich nicht.
Ich habe eine JavaFx anwendung, die so auch super Funktioniert. Diese möchte ich jetzt auf meinem Handy zum Laufen bringen. 

Hier erstmal die Fx variante



Spoiler: JavaFx Code





```
public class Main extends Application {

    private double xOffset = 0;
    private double yOffset = 0;

    @FXML
    TextField input;
    @FXML
    TextArea output;
    @FXML
    Text time;

    String word;

    List<String> wordList = new ArrayList<String>();
    List<String> foundWords = new ArrayList<>();

    String list;

    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("Ui.fxml"));// Mit Scenebuilder verknüpfen
            Scene scene = new Scene(root, 400, 500);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

            primaryStage.initStyle(StageStyle.TRANSPARENT);

            root.setOnMouseClicked(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    xOffset = event.getSceneX();
                    yOffset = event.getSceneY();
                }
            });

            // move around here
            root.setOnMouseDragged(new EventHandler<MouseEvent>() {
                @Override
                public void handle(MouseEvent event) {
                    primaryStage.setX(event.getScreenX() - xOffset);
                    primaryStage.setY(event.getScreenY() - yOffset);
                }
            });

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // Workprogress
    public void progress() {
        MediaPlayer musicplayer;
        Media mp3MusicFile = new Media(getClass().getResource("dontdrop.mp3").toExternalForm());

        musicplayer = new MediaPlayer(mp3MusicFile);
        musicplayer.setAutoPlay(true);
        musicplayer.setVolume(0.2); // from 0 to 1
        
        
        Instant starts = Instant.now();
        word = input.getText().toUpperCase();
        char[] wordChars = word.toCharArray();

        try {
            
            
            InputStream is = getClass().getResourceAsStream("wortliste.txt");
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader read = new BufferedReader(isr);
            
        

            Arrays.asList(wordList);

            while ((list = read.readLine()) != null) {
                wordList.add(list);

            }
            read.close();

        } catch (Exception e) {
            e.getMessage();
        }
        System.out.println("text eingelesen");

        for (String w : wordList) {
            for (char letter : wordChars) {
                if (word.indexOf(letter) > 0 && foundWords.indexOf(w) < 0 && w.length() <= wordChars.length
                        && notTooManyLetters(w.toCharArray(), wordChars) && sameLetters(w.toCharArray(), wordChars)) {
                    foundWords.add(w);
                }
            }
        }

        System.out.println(foundWords.toString());
        output.setText(foundWords.toString());


        Instant ends = Instant.now();

        time.setText(Duration.between(starts, ends).toMillis() / 1000d + " Secs");
        
    };

    // Work Button
    public void handelabc(ActionEvent event) {
        progress();

        
        

    }

    // Exit Button
    public void handelquit(ActionEvent event){

        
        Platform.exit();
        }

    

    // New Window on Button
    public void handleInfo(ActionEvent event) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("Info.fxml"));
            Stage stage = new Stage();
            stage.setScene(new Scene(root, 300, 300));
            stage.setTitle("INFO ©Marcus Ferl");
            stage.show();

            MediaPlayer musicplayer;
            {

                Media mp3MusicFile = new Media(getClass().getResource("sonic.mp3").toExternalForm());

                musicplayer = new MediaPlayer(mp3MusicFile);
                musicplayer.setAutoPlay(true);
                musicplayer.setVolume(0.2); // from 0 to 1

                stage.setOnCloseRequest(new EventHandler<WindowEvent>() {

                    @Override
                    public void handle(WindowEvent event) {
                        musicplayer.stop();

                    }
                });

            }

        } catch (IOException e) {

            e.getMessage();
        }

    }

    public static int getNumValue(char[] string, char val) {
        int count = 0;
        for (char c : string) {
            if (c == val) {
                count++;
            }
        }
        return count;
    }

    public static boolean notTooManyLetters(char[] word, char[] wordChars) {
        for (char letter : wordChars) {
            if (getNumValue(word, letter) > getNumValue(wordChars, letter)) {
                return false;
            }
        }
        return true;
    }

    public static boolean sameLetters(char[] w, char[] wordChars) {
        for (char letter : w) {
            if (new String(wordChars).indexOf(letter) < 0) {
                return false;

            }

        }
        return true;
    }

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




Diesen hab ich nun versucht mittels Android Studio auf ein Mobile device zu übertragen.
Im endeffekt scheitert es an der Foreach - Schleife, welche immer in einem false endet, ich kann mir aber nicht erklären warum.

Hier mein Android Studio Code


Spoiler: Android Code





```
public class MainActivity extends AppCompatActivity {

String word;
String list;
char[] wordChars;
List<String> wordList = new ArrayList<String>();


EditText input;
TextView output;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    input = (EditText) findViewById(R.id.input);
    output = (TextView) findViewById(R.id.output);

}


/*
Read Textfile
*/
public void readTextfile() {
    BufferedReader read = null;
    try {
        read = new BufferedReader(
                new InputStreamReader(getAssets().open("test.txt")));


        Arrays.asList(wordList);

        while ((list = read.readLine()) != null) {
            wordList.add(list);
        }
        read.close();

    } catch (Exception e) {
        e.getMessage();
    }
    Log.i("ListRead", "Done"); }

public static int getNumValue(char[] string, char val) {
    int count = 0;
    for (char c : string) {
        if (c == val) {
            count++;
        }
    }
    return count;
}

public static boolean notTooManyLetters(char[] word, char[] wordChars) {
    for (char letter : wordChars) {
        if (getNumValue(word, letter) > getNumValue(wordChars, letter)) {
            return false;
        }
    }
    return true;
}

public static boolean sameLetters(char[] w, char[] wordChars) {
    for (char letter : w) {
        if (new String(wordChars).indexOf(letter) < 0) {
            return false;

        }

    }
    return true;
}

// Create Result
public void compare() {

    List<String> foundWords = new ArrayList<String>();
    word = input.getText().toString().toUpperCase();
    wordChars = word.toCharArray();

    for (String w : wordList) {
        for (char letter : wordChars) {
            if (word.indexOf(letter) > 0 && foundWords.indexOf(w) < 0 && w.length() <= wordChars.length
                    && notTooManyLetters(w.toCharArray(), wordChars) && sameLetters(w.toCharArray(), wordChars)) {
                foundWords.add(w);
            } else {
                if (foundWords.size() <= 0) {
                    Log.i("CheckList", "Empty List!");
                }
            }
        }
    }
    output.setText(foundWords.toString());
}

public void onKlickAbc(View view) {
    readTextfile();
    compare();


}}
```





Wie schon gesagt, ich bin Anfänger und vermute, dass es etwas mit dem Android lifecycle zu tun hat. Wenn es damit zu tun hat, versteh ich die Umsetzung nicht. Die Methode, die das Textfile einliest funktioniert ja auch einfandfrei. Warum dann nicht die, welche alles verarbeitet?


----------



## spike86 (26. Mai 2020)

Ich verzweifel echt noch :-( 
Keiner da, der mir helfen kann?


----------



## mihe7 (27. Mai 2020)

Wenn Du vielleicht noch dazuschreibst, bei welcher for-Each-Schleife es scheitert, dann könnte man sich das ansehen. Ich frage mich allerdings, an welcher Stelle die Methode onKlickAbc überhaupt aufgerufen wird.


----------



## spike86 (27. Mai 2020)

Die ist mit einem Button verknüpft. Funktioniert auch bis zu dem Teil hier:



```
for (String w : wordList) {

        for (char letter : wordChars) {

            if (word.indexOf(letter) > 0 && foundWords.indexOf(w) < 0 && w.length() <= wordChars.length

                    && notTooManyLetters(w.toCharArray(), wordChars) && sameLetters(w.toCharArray(), wordChars)) {

                foundWords.add(w);

            } else {

                if (foundWords.size() <= 0) {

                    Log.i("CheckList", "Empty List!");

                }

            }
```

Und wie erwähnt, die Kernfunktion dieses Programmes läuft überall nur mit Android Studio nicht. Hab es als normales Java Programm probiert, per Scanner eine Buchstaben Kombination einlesen lassen und dann die gefundenen Wörter ausgegeben, klappt.

In JavaFx ebenfalls, Buchstaben werden eingelesen, verglichen und gefundene Wörter ausgegeben.

Im Android Studio bleibt die foundWords Liste einfach leer, und ich kann mir nicht erklären warum...


----------



## LimDul (27. Mai 2020)

Aus dem Bauch heraus mit dem Debugger ran gehen und schauen, was für werte die einzelnen Variablen haben und was die Methoden zurück geben. Eventuell gibt es seltsame Zeichensatzprobleme, dass etwas sich anders verhält als woanders.


----------



## lam_tr (27. Mai 2020)

spike86 hat gesagt.:


> Hallo Leute,
> 
> zuerst muss ich betonen, dass ich Java\JavaFx anfänger bin, also bitte verurteilt mich nicht.
> Ich habe eine JavaFx anwendung, die so auch super Funktioniert. Diese möchte ich jetzt auf meinem Handy zum Laufen bringen.
> ...


Warum benutzt du nicht jfxport um den JavaFX Code nicht mehr umschreiben zu müssen und direkt auf Android laufen zu lassen?


----------



## spike86 (27. Mai 2020)

lam_tr hat gesagt.:


> Warum benutzt du nicht jfxport um den JavaFX Code nicht mehr umschreiben zu müssen und direkt auf Android laufen zu lassen?



Hab ich auch schon probiert, aber leider nicht hinbekommen. Erst hab ich Fehler bekommen wegen der gradle Version, das hab ich in den Griff bekommen. Dann Fehler weil die java.exe nicht gefunden wurde oder ausgeführt werden konnte...und und und...Allgemein hatte ich mit jfxport am Ende mehr Probleme als ich wollte.

Ich habe schon sehr viel Zeit für verschiedene Lösungswege investiert, was mich dann langsam demotiviert hat, weswegen ich mich dann hier ans Forum gewendet habe.

Vielleicht nochmal zur Erklärung wie das ganze funktionieren soll*.*
Ein Texteingabefeld in dem man verschiedene Buchstaben eingibt. "ALAS"
Diese werden dann mit Wörtern in einer Liste abgeglichen. "AS, SAAL ,TEST ,HALLO, ALS"
Ausgabe wäre dann in einem Textview
"AS, ALS, SAAL"


----------



## mihe7 (27. Mai 2020)

Mach, was @LimDul geschrieben hat und geh das mal mit dem Debugger durch.


----------



## spike86 (28. Mai 2020)

Also hab es nun hinbekomme.


```
word = input.getText().toString().toUpperCase();
    wordChars = word.toCharArray();
```

an dieser Stelle wurde mir der array "char [] word" nicht befüllt, ist leer geblieben. Ich habe alle imports gelöscht, neu gestartet, alles wieder importiert, was importiert werden musste, und dann ging es... ich hab keine Ahnung, warum wieso weshalb.



Nun habe ich aber ein neues Problem, die Liste zum abgleich die ich habe, ist 34 mb groß und enthält demensprechend viele wörter. Leider bekomme ich nun ein Timeout, wenn ich es mit dieser Probiere, wie bekomme ich es hin, das die app schneller vergleicht?
Testliste bestand nur aus 10 Wörtern, deshalb hat es damit super geklappt.


----------



## LimDul (28. Mai 2020)

Beschreib mal deine Anforderung, was genau passieren soll. 


> Ein Texteingabefeld in dem man verschiedene Buchstaben eingibt. "ALAS"
> Diese werden dann mit Wörtern in einer Liste abgeglichen. "AS, SAAL ,TEST ,HALLO, ALS"
> Ausgabe wäre dann in einem Textview
> "AS, ALS, SAAL"


Wenn ich das richtig interpretiere, möchtest du wissen welche Wörter aus deiner Liste sich aus der Eingabe (bzw. aus einem Subset der Eingabe) darstellen lassen? Korrekt?

Wenn ja - dann ist char Vergleich hochgradig inperformant, sondern man sollte es auf ein simplereres Problem zurückführen.

Idee: Anstelle über die Chars und Reihenfolge zu gehen - die Reihenfolge ist vollkommen irrelevant bei dem Problem. Relevant ist nur - kommen die Zeichen aus den Testwörtern alle in deiner Eingabe vor.

Also interessiert dich doch nur:  Wie oft kommt der Buchstabe A im Testwort vor? Kommt er in der Eingabe mindestens genau so oft vor? (Und das für alle 26 Buchstaben). Das kann man - insbesondere unter Android - mit Sicherheit auch in einer sinnvollen Datenbankstruktur (Sqlite) ablegen. (Im Zweifellsfall eine Tabelle mit 27 Spalten - Dem Wort und jeweils wie oft die Buchstaben A bis Z vorkommen). Wenn du dann ALAS eingibst, willst du nur noch die Zeilen haben wo gilt:

* Anzahl A kleiner gleich 2
* Anzahl B gleich 0
* ...
* Anzahl L kleiner gleich 1
* ...
* Anzahl S kleiner gleich 1

Dann musst das ganze Zeug nicht umbedingt komplett im Speicher halten.


----------



## mihe7 (28. Mai 2020)

Man könnte auch die Zeichen sortiert in einer Spalte ablegen...


----------



## LimDul (28. Mai 2020)

mihe7 hat gesagt.:


> Man könnte auch die Zeichen sortiert in einer Spalte ablegen...


Da kommt mir noch eine weitere Idee.

Das Wort "SAAL" wird zusätzlich noch als reguläre Ausdruck gespeichert:

```
String patternSaal = ".*A{2}.*L{1}.*S{1}.*".
```
Dann die eingebenen Buchstaben sortieren und matchen gegen die Ausdrücke


----------



## spike86 (28. Mai 2020)

Nochmal vielen danke für die Hilfe, ich war echt froh, dass die App nun läuft. Mit Datenbankstrukturen habe ich mich noch nicht befasst, kommt dann noch, die App war oder ist ein Projekt um zu testen was ich, mit meinen jetzigen Java Kenntnissen leisten kann. Um die App zu verbessern muss ich nun weiter lernen um weiter zu kommen. Also alles schritt für schritt, somit bin ich wieder vollstens motiviert


----------

