2016-04-06 14 views
1

Ich schreibe ein Text-basierte Abenteuer-Spiel und ich lief in ein Problem. Ich portiere es von Terminal zu JFrame GUI und ich brauche es auf Benutzereingaben warten, bevor Sie fortfahren. Ich habe ein System mit einer booleschen Variablen namens buttonPressed eingerichtet, die als falsch beginnt. Wenn die Schaltfläche "Senden" gedrückt wird, wird sie auf "wahr" gesetzt. Es gibt eine while-Schleife, die darauf wartet, dass die Schaltfläche wahr wird, bevor sie dem Programm erlaubt, fortzufahren, wobei das Programm im Wesentlichen angehalten wird, bis der Benutzer die Eingabe vornimmt. Das Problem ist, das funktioniert nur, wenn ich in der while-Schleife eine system.out.println-Zeile geschrieben habe. Sonst geht es nicht weiter, nachdem ich auf die Schaltfläche geklickt habe. Was ist das Problem?Java-Programm stecken in während Schleife

public class event implements ActionListener{ 
    public void actionPerformed(ActionEvent e){ 
     moves += 1; 
     movesLabel.setText("Moves: " + moves); 

     buttonPressed = true; 

     try{ 
      input = (String)(textfield.getText()); 
      textfield.setText(""); 

     }catch(Exception ex){ 
      textfield.setText("Error"); 
     } 
    } 
} 


public static void main (String args[]) { 
    Main gui = new Main(); 
    gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    gui.setVisible(true); 
    gui.setSize(650, 350); 
    gui.setTitle("Sprinkles Text Adventure"); 

    setInventory(); 

    textArea.setText(textDisplay("Welcome Adventurer!")); 
    textArea.setText(textDisplay("What is thy name: ")); 

    while(!buttonPressed){ 
     // this only works when I have system.out.println("something") written in 
    } 

    buttonPressed = false; 

    textArea.setText(textDisplay(input)); 

    if ("alice".equals(input)||"Alice".equals(input)){ 
     textArea.setText(textDisplay("Stop toking the magical pipe, ")); 
     textArea.setText(textDisplay("you aren't alice and this isn't wonderland")); 
     textArea.setText(textDisplay("Now down the rabbit hole you go!")); 
    } 
    else if ("l3ikezI".equals(input)||"l3ikezi".equals(input)){ 
     System.out.println("Magic and Technology flows through your veins"); 
     System.out.println("Welcome back, Master"); 
     for(int j = 0; j<14; j++){ 
      Chest[j]=1; 
     } 
    } 
    else{ 
     System.out.println("Enter " + input + " and good luck!\n\n"); 
    } 
+0

Haben Sie 'Button definiert '? – Nick

+0

ja, oben initialisiere ich es mit privaten statischen boolean buttonPressed = false; Es ist komisch, weil es funktioniert, wenn ich diese Codezeile in –

+0

habe Dann würde ich vermuten, dass die JVM leere Endlosschleifen überspringt. Vielleicht könntest du Thread.sleep (15) benutzen? – Demurgos

Antwort

2

Im kein Java-Experte, aber ...
Es sieht aus wie Sie nicht Ihre GUI-Thread Zeit, um alles zu tun, da Sie busy waiting für Ihre boolean zu ändern sind. Um dies zu beheben, sollten Sie wahrscheinlich eine semaphore verwenden. Oder, die leichtere (dreckige) Lösung, rufen Sie eine sleep() in Ihrer while-Schleife. Für Java spezifische Dinge, siehe this Frage.

Auf den zweiten Gedanken fand ich, dass Java ein volatile Schlüsselwort hat. Ich weiß nicht, ob buttonPressedvolatile deklariert ist, aber wenn es nicht ist, könnte der Compiler entscheiden, dass, da die While-Schleife leer ist, der Wert nie zu Änderungen wechselt und es durch while(true) als eine Optimierung ersetzt. Diese

1

...

while(!buttonPressed){ 
    // this only works when I have system.out.println("something") written in 
} 

ist nur Ärger bringen, abgesehen von der Tatsache, dass Sie nicht garantieren können, welche Thread main tatsächlich in genannt, die in Ihnen die Blockierung der Event-Dispatching Thema führen könnte, es ist nur der falsche Ansatz.

Anstatt eine JFrame zu verwenden, möchten Sie ein modales JDialog von irgendeiner Art verwenden, die die Ausführung des Codes an dem Punkt blockiert, an dem der Dialog sichtbar gemacht wird, bis er entsorgt wird und was Sie auf sichere Weise tut kann es im Rahmen des EDT verwenden. Weitere Informationen finden Sie unter Initial Threads, Concurrency in Swing und How to Make Dialogs.

Als allgemeine Ratschlag, nicht direkt aus der Top-Level-Container wie JFrame und JDialog erstreckt, und statt opt ​​so etwas wie JPanel verwenden, es befreit Sie und erhöht die Wiederverwendbarkeit Ihrer Komponenten

Verwandte Themen