2016-04-06 5 views
1

私はテキストベースのアドベンチャーゲームを書いていますが、問題が発生しました。私はそれをターミナルからJFrameのGUIに移植しています。進める前にユーザーの入力を待つ必要があります。私は、falseとして始まるbuttonPressedと呼ばれるブール変数があるシステムをセットアップします。送信テキストボタンが押されると、テキストボタンがtrueに変わります。プログラムを続行する前に、ボタンがtrueになるのを待っているwhileループがあり、ユーザーが入力を送信するまでプログラムを本質的に一時停止します。問題は、これはwhileループ内にsystem.out.println行が書き込まれている場合にのみ機能します。それ以外の場合は、ボタンをクリックしても処理が継続しません。どうしたの?あなたが変更するには、あなたのブールのためbusy waitingあるので、あなたは、何かをするためにあなたのGUIスレッドの時間を与えていないように見えますJavaプログラムがwhileループ中に突き当たりました

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

あなたは 'のbuttonPressed定義しているあなたのコンポーネントの再利用性を高めます'? – Nick

+0

はい、上にプライベート静的なブール値でそれを初期化するbuttonPressed = false;それは私がコードの1行を持っているときに動作するので変です。 –

+0

次に、JVMが空の無限ループをスキップすると思います。多分あなたはThread.sleep(15)を使うことができますか? – Demurgos

答えて

2

イムなしのJavaの専門家ではなく...
。 これを解決するには、おそらくsemaphoreを使用してください。または、簡単(汚れた)解決方法は、whileループでsleep()と呼んでください。 Java固有のものについては、thisの質問をご覧ください。

2番目の考えでは、javaにはvolatileというキーワードがあります。 buttonPressedvolatileと宣言されているかどうかはわかりませんが、そうでない場合、コンパイラはwhileループが空であるためその値が変更されることはないと判断し、while(true)を最適化として置き換えます。

1

この...

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

はただ、あなたがイベントディスパッチスレッドをブロックすることにつながる可能性があり、離れてあなたが実際にあると呼ばれるものスレッドmain保証することができないという事実から、トラブルを求めていますそれはちょうど間違ったアプローチです。

JFrameを使用する代わりに、ある種類のモーダルJDialogを使用すると、ダイアログが表示/非表示にされ、安全な方法で表示されるようにコードの実行をブロックしますEDTの文脈の中でそれを使用することができる。

詳細については、Initial Threads,Concurrency in SwingおよびHow to Make Dialogsをご覧ください。

はアドバイスの一般的な作品として、JFrameJDialog、代わりにJPanelようなものを使用してのオプトインのようなトップレベルのコンテナから直接拡張避けるため、それはあなたを解放し、

関連する問題