java程序卡在while循环中

时间:2016-04-06 20:20:25

标签: java loops user-interface while-loop jframe

我正在写一个基于文本的冒险游戏,但我遇到了一个问题。我正在将它从终端移植到JFrame GUI,我需要它在继续之前等待用户输入。我建立了一个系统,其中有一个名为buttonPressed的布尔变量,它以false开头。按下提交文本按钮后,将其更改为true。有一个while循环在允许程序继续之前等待按钮变为true,基本上暂停程序直到用户提交输入。问题是这只有当我在while循环中写入一个system.out.println行时才有效。否则它在我点击按钮后不会继续。有什么问题?

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");
    }

2 个答案:

答案 0 :(得分:2)

我不是java专家但是......
看起来你没有给你的gui线程时间做任何事情,因为你的布尔值是busy waiting来改变。 要解决此问题,您应该使用semaphore。或者,更简单(脏)的解决方案,在while循环中调用sleep()。 对于特定于Java的内容,请查看this问题。

第二个想法,我发现java有volatile个关键字。我不知道buttonPressed是否被声明volatile,但如果不是,编译器可能会决定,因为while循环是空的,它的值永远不会改变,并替换它由while(true)作为优化。

答案 1 :(得分:1)

此...

#Include "CompareImagesUDF.au3"

; Define the two images (They can be different file formats)
$img1 = "Image1.jpg"
$img2 = "Image2.jpg"

; Compare the two images
$duplicateCheck = _CompareImages($img1, $img2)
MsgBox(0,"Is Duplicate?", $duplicateCheck)
除了你无法保证实际调用了什么线程while(!buttonPressed){ // this only works when I have system.out.println("something") written in } ,这可能导致你阻止事件调度线程,这只是一个错误的方法。只是要求麻烦。 p>

您想要使用某种类型的模态main,而不是使用JFrame,这将阻止代码在对话框可见之前执行,直到它被处理/关闭为止以安全的方式做到这一点,所以你可以在EDT的背景下使用它。

请查看Initial ThreadsConcurrency in SwingHow to Make Dialogs了解详情。

作为一般建议,请避免直接从顶级容器(例如JDialogJFrame)进行扩展,而是选择使用类似JDialog的内容,这样可以释放您并提高可重用性您的组件