Java FX Warten auf Textfield eingabe

undercover

Aktives Mitglied
Main Leute,

habe folgende Frage.
Ich habe ein Programm geschrieben welches eine Eingabe über die Konsole in Form eines Strings erwartet. Ist diese Eingabe Korrekt führt das Programm nachfolgende Schritte aus, ist es nicht korrekt geht es in eine Schleife und bittet jedesmal nach prüfen auf korrekte Eingabe mittels .equals("....") die Eingabe zu wiederholen.
Nun wollte ich eine GUI implementieren die mittels TextField und ConfirmButton ,oder nur Button, ebend diesen korrekten Befehl in das Programm feuert das es startet.
Leider bekomme ich es nicht hin. Ich lese die eingabe mittels .getText() aus dem TextField und setzt es in ein Feld String input.
Natürlich ist input es beim starten der GUI auf null gesetzt, das hat zur Folge das eine NullPointerException ausgelöst wird. Inizialisiere ich input direkt mit dem korrekten Befehl geht es natürlich automatisch los ohne das ich etwas eingebe.
Am liebsten wäre es mir , wenn ich sowohl per Konsole den Befehl eingeben kann mittels inputReader.nextLine(); und per Texteingabe im TextField ( oder nur per Button der den Befehlt direkt übergibt).
Habt ihr eine Idee?
 
Natürlich ist input es beim starten der GUI auf null gesetzt, das hat zur Folge das eine NullPointerException ausgelöst wird.
Zu dem Satz würde ich gerne mal den Code sehen.
Eine NPE kann da eigentlich nur fliegen, wenn du mit dem besagten String etwas machst bevor er durch das TextFeld initialisiert ist.

Generell wäre es nicht schlecht dein Code zu sehen um dir (schneller) helfen zu können

Gruß Robert 🙂
 
Dir ist aber schon klar das man mit if(variable == null) prüfen kann ob eine Variable noch nicht initialisiert ist und entsprechend handeln kann oder?
 
Ist mir bekannt.
Java:
String input = inputReader.nextLine();
while (!input.equals("run")) {
                System.out.println("User " + actualUser.number +
                        " ist am Zug. Schreibe 'run' um sich zu bewegen.");
                input = inputReader.nextLine();
            }
            move(actualUser.run());
So ist es wenn ich es über die Konsole spiele. Möchte nun eine geänderte Version haben für die GUI.
Das ganze soll entweder einfach per Button ausgelöst werden, oder per TextField und Button , was eleganter zu lösen wäre.
 
Was hast du denn bereits? Du sagtest in deinem Ausgangspost was von einem String, einem TextFeld und einer NPE.
Poste doch bitte den relevanten Code zstl. StackTrace und Zeile wo die NPE fliegt.
 
Das mit dem String und dem TextField war eine Idee, dass der Benutzer in das TextField "run" eintippt und die Methode move(..)auslöst wird. Mir wäre es sogar lieber wenn ich nur einen Button klicke und das die Methode move(..) aufruft.
Bei meinem aktuellen Versuch habe ich das Textfeld weggelassen und es sieht folgendermaßen aus :
Im Controller habe ich folgendes :
Java:
static boolean klick;
  
    public void handleRun(ActionEvent e){
        setKlick(true);
              
    }

public void setKlick(boolean klick){
        this.klick = klick;
    }

public boolean getKlick() {
        return klick;
    }

Meine Model. Passt natürlich vorne und hinten nicht, da klick = !true bricht es sofort ab, ich habe keine Möglichkeit durch drücken des Button klick = true zu setzten.
Java:
public void startGameGUI() {
        boolean klick = Controlller.getKlick();
      
        while (getGewinner() == null) {
            if(klick == !true){
            actualUser = getActualUser();
            System.out.println("User " + actualUser.number +
                    " ist am Zug. Bitte roll drücken.");
            }else{
                actualUser = getActualUser();
                move(actualUser.run());
          
            }
 
So 100%ig hab ich dein vorgehen noch nicht durchschaut .. Hier mal folgender Vorschlag:

Du hast wie gewohnt deine Application Klasse die dein UI startet. In deinem Controller deklariert du einfach eine Instanz deiner Model Klasse und initialisierst es in der initialize() Methode. Jetzt kannst du ja ganz bequem deinem Button die handleRun(..) Methode zuweisen und dort all das machen was du möchtest. Also schauen was in dem Textfeld drin steht, von einem Spieler die move() Methode ausführen etc etc.

BTW: Der Vorschlag ist ins Blaue geraten, da ich deine vollständige Projektstruktur nicht kenne.

Es kann auch sein dass für dein Problem eine bequemere Lösung gibt. So viel hab ich mit JavaFX noch nicht gearbeitet 😛

Gruß Robert
 
Ja das ist schwierig, nur umfasst das eigentliche Programm ca 13 Klassen^^ was hier den Rahmen sprengen würde.
Extrem vereinfacht gesagt, ich möchte in der startGameGUI() Methode welche in meiner Model Klasse implementiert ist , per Knopfdruck die Methode move(..) aufrufen. Nach Ausführen der Methode soll er wieder die Abbruchbedingung prüfen, wenn nicht erfüllt dann wieder per Knopfdruck die Methode ausführen usw...
Das Problem , ich bekomme es nicht hin das er auf den Knopfdruck wartet. Wenn ich es über die Konsole ausführe wartet er aufgrund der String input = inputReader.nextLine() Zuweisung und alles ist gut.
Danke für die Hilfe, die GUI treibt mich in den Wahnsinn!
 
Um ehrlich zu sein klingt mir das nach einem recht konfusem Konstrukt. Die Model Klasse soll die GUI starten, dort dann auf eine GUI Komponente reagieren und entscheiden wie es danach weiter geht? Denk immer daran das man sagt, dass UI und Logik immer getrennt von einander behandelt werden sollen. Vorher 30 Minuten hinsetzten, mit Zettel und Stift und aufmalen was man eigentlich erreichen will erspart einem im nachhinein viel Arbeit.

Wie im Post #2 schon mal angesprochen ist es, ohne weiteren Code zu sehen, recht schwierig hier auf eine Lösung zu schließen. JavaFX baut nun mal (mehr oder minder) auf dem MVC Pattern auf. Wenn du einen anderen Weg eingeschlagen hast dann solltest du zmd. mal von den relevanten Klassen ein bisschen mehr preisgeben. Bspw. Sieht man in deinem 2. Codebeispiel in Post #6 was von Controller.getClick(). Wie initialisierst du denn die Controller Variable? Was ist denn jetzt mit der genannten NPE aus deinem Ausgangspost? Ist die noch akutell?

Normalerweise hättest du deine Application Klasse (View), diese hat ihren Controller wo bspw ButtonEvents gehandelt werden und über diese Controller Klasse kannst du dann dein Model wissen lassen dass sich Daten verändert haben. Das wäre so der gängige Weg. Wie du dein Projekt aufgebaut hast ist mir nach 8 Posts immer noch unklar.
 
Nein. Also ich habe mehrer Klassen, 13 an der Zahl , diese gehören zu meinem Hauptprogramm. Im nachhinein wollte/will ich eine GUI dazu implementieren.
Die Klassen des Hauptrogramms dienen als Model , die FXML Datein die ich im SceneBuilder erstellt habe sind meine Views und dann habe ich Controller Klassen wie z.B. dem hier gezeigten Controller.
Der Ablauf sieht so aus. Ich starte meine GUI aus der Klasse Main im Package der GUI.
In der ersten scene wähle ich eine Anzahl von Usern, per klick auf einen next Button öffnet sich eine neue scene(erfolgt alles im dazugehörigen Controller und handle Methode des Button)da kann ich den Usern Nummern zuweise. Danach klicke ich wieder auf einen Button next, dieser Klick öffnet nun die scene(auch im dazugehörigen Controller mit der handle Methode des Button) mit meinem run Button und startet die Methode startGameGUI() welche im Model implementiert ist. Der Name startGameGUI() ist nur so gewählt da es noch eine startGame() gibt die ich über die Konsole spielen kann.
In der startGameGUI läuft sozusagen jetzt alles weitere ab. Ich möchte eine Verbindung aus der startGameGUI und meinem Controller der scene 3 mit dem run Button haben.
Die Methode move() soll erst ausgeführt werden wenn ich in der GUI den run Button anklicke, ansonsten soll das Programm anhalten.

Alles sehr kompliziert als Neuling, besonders treffend zu formulieren was man hat und was sein soll ^^
Ist es so klarer was überhaupt passiert?
 
DAs wird auch nichts werden solange du mit dem SceneBuilder UI's erstellst und nicht den Ansatz einer Ahnung hast was da eigentlich für ein Code erzeugt wird und wie dieser funktioniert. Gerade JavaFX finde ich da für den UI Einstieg sehr schwierig. Erzeuge deine ersten UI's von Hand indem du allen Code selber schreibst. Wenn Du dann verstanden hast was da abläuft dann kannst du ein Helfertool benutzen.
 
Ich habe JavaFX auch anfangs nur über XML erzeugt (und war/bin recht happy damit). Code und XML sind am Ende von der Struktur her recht ähnlich. Aber eines stimmt: Es bringt nichts, nur SceneBuilder zu nutzen und nie einen Blick in die XML zu werfen.
Das Wichtige ist, dass man ordentliche Controller baut und ich denke, dass hier die Trennung von XML und Controller schon enorm hilft, das Prinzip von MVC zu verinnerlichen.
Wenn dein Programm zu umfangreich ist: Du kannst hier auch Zips als Anhang zu einem Post hinzufügen. Dann hätten wir etwas. Oder du erstellst auf Github einen Gist - oder legst ein Repository mit den Daten an, wir schauen rein und wenn alles fertig ist, löscht du das Repository wieder. Alles kein unlösbares Problem.
 
Wo ist das Problem seine Views per Tool zusammenzuklicken?
- im View ist kein Logik
- der Zugriff auf die Komponenten ist genau so als hätte man sie händisch erzeugt
 
Eigentlich ist der weitere Code des Hauptprogramms recht uninteressant. Den darin ist nur der Aufbau des Spiels enthalten.
In der Methode startGameGUI() oder startGame() läuft alles ab, sobald das Spiel erstellt wurde.
Ich muss es nur noch schaffen das das Programm während es die while in der Methode durchläuft jedesmal auf den Button klick wartet. Alles andere im Hauptprogramm dient der Erzeugung des Spiels und ist beim Aufruf der Methode schon gelaufen und klappt.
Schade, ich dachte es ist etwas simpler mit einer Methode wie wait() etc.
@Thallius , da gebe ich dir Recht, ich benötige das für eine Abgabe, sonst würde ich mir auch die Zeit nehmen.
Danke trotzdem für die Mühe 🙂
 
Bin mir immer noch nicht sicher, was du erwartest. Ohne Code werden wir einfach nichts genaueres sagen können. Damit musst du eben leben.
 
Was benötigst du denn genau ? Die FXML Datei? Den Controller habe ich ja komplett gepostet, ebenso die Methode die mit der GUI verknüpft werden soll. Sonst ist nix im Programm was mit der GUI verknüpft ist, ich habe noch nix weiter vorgenommen.
 
Wenn deine Beziehungen, so wie du sie in Post #10 aufgemalt hast, stimmen sollte es doch kein Problem sein so vorzugehen wie ich es bereits in Post #7 vorgeschlagen habe.

Deine GUI wird geöffnet und der Controller geladen. Im Controller initialisierst du ein neues Game-Objekt über das du dann in der #handleRun(..) deine o.g. Methoden (move(..),.. etc) ausführen kannst. So wird immer nur wenn du den Button betätigst auch die move Methode ausgeführt. Das ist doch genau das was du willst, oder nicht?
 
Wenn deine Beziehungen, so wie du sie in Post #10 aufgemalt hast, stimmen sollte es doch kein Problem sein so vorzugehen wie ich es bereits in Post #7 vorgeschlagen habe.

Deine GUI wird geöffnet und der Controller geladen. Im Controller initialisierst du ein neues Game-Objekt über das du dann in der #handleRun(..) deine o.g. Methoden (move(..),.. etc) ausführen kannst. So wird immer nur wenn du den Button betätigst auch die move Methode ausgeführt. Das ist doch genau das was du willst, oder nicht?

Es hat geklappt. Ich hatte die ganze Zeit eine NPE, da ich eine neue Instanz im Controller erstellt habe dessen Felder mit null und 0 inizialisiert wurden.
Die Lösung war, was Ihr nicht sehen konntet da der code fehlte, ich habe habe zuvor mithilfe einer vorhergegangenen Scene eine Instanz vom Spiel verändert und sie in der dazu gehörigen Model Klasse gespeichert . Diese Instanz aus der Model Klasse musste ich in meiner Controller Klasse per setter holen und dann in meiner handleRun(..) verwenden.
@Robat du hast mich mit auf die richtige Spur geschickt, vielen Dank!
@all, danke für die Hilfe, jeder Post war hilfreich!
Ich muss mich definitiv intensiv mit dem MVC Pattern beschäftigen. So wie das aktuell dasteht ist es lauffähig, aber sicher nicht konform dem MVC Pattern.
 

Zurück
Oben