1

I'm writing a text based adventure game and I ran into a problem. I'm porting it over from terminal to JFrame GUI and I need it to wait for user input before proceeding. I set up a system where there is a boolean variable called buttonPressed which starts out as false. When the submit text button is pressed it changes it to true. There is a while loop that waits for the button to become true before it allows the program to continue, essentially pausing the program until the user submits input. The problem is this only works when I have inside the while loop a system.out.println line written in. Otherwise it doesn't continue after I click the button. What's the problem?

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");
    }
6
  • Have you defined buttonPressed? Commented Apr 6, 2016 at 20:26
  • yes, on top i initialize it with private static boolean buttonPressed = false; It's weird because it works when I have that one line of code in Commented Apr 6, 2016 at 20:26
  • Then I would guess that the JVM skips empty infinite loops. Maybe you could use Thread.sleep(15) ? Commented Apr 6, 2016 at 20:27
  • buttonPressed definition is missing... Looks like you have two of them? Hard to say with incomplete code. Commented Apr 6, 2016 at 20:37
  • Could you provide more code? How do you attach ActionListener to the button? Commented Apr 6, 2016 at 20:37

2 Answers 2

2

Im no java expert but...
It looks like you are not giving your gui thread time to do anything, since you are busy waiting for your boolean to change. To solve this you should probably use a semaphore. Or, the easier (dirty) solution, call a sleep() in your while loop. For java specific things, look at this question.

On second thought, I found that java has a volatile keyword. I don't know if buttonPressed is declared volatile, but if it is not, the compiler might decide that, since the while-loop is empty, its value is never going to changes, and replaces it by while(true) as an optimisation.

Sign up to request clarification or add additional context in comments.

Comments

1

This...

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

is just asking for trouble, apart from the fact that you can't guarantee what thread main is actually called in, which could result in you blocking the Event Dispatching Thread, it's just the wrong approach.

Instead of using a JFrame, you want to use a modal JDialog of some kind, which will block the code's execution at the point the dialog is made visible until it is disposed/closed and which does it in safe manner so you can use it within the context of the EDT.

Take a look at Initial Threads, Concurrency in Swing and How to Make Dialogs for more details.

As a general piece of advice, avoid extending directly from top level containers like JFrame and JDialog and instead opt of using something like JPanel, it frees you up and increases the reusability of your components

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.