Frage

I start my GUI like this, which seems correct.

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame gui = new JFrame();
            gui.setExtendedState(JFrame.MAXIMIZED_BOTH);
            gui.setVisible(true);
        }
    });

At a certain point in the application, the playTurn() method gets fired. The for loops all turns in the list.

 for (String turn : controller.getTurns()) {
                playTurn(turn);
            }

I now load the correct panel with my CardLayout which worked fine. Then I had to write the playTurn() method. So playTurn() gets called. It should do certain things according to some variables. But it should not return until some buttons are disabled. This is what I can't achieve, the program just stops working. I can guess it's in the direction of threads etc.. but can't seem to figure it out. Thanks in advance.

public void playTurn(String turn) {
    if (controller.givePlayers().contains(turn)) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                while (!turnFinished) {
                    if (!button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled()) {
                        turnFinished = true;
                    }
                }
            }
        });
    } else {
        deletePlayer(turn);
    }
}

Sorry for bad formatting. Couldn't find where.

EDIT: The GUI stops being responsive. Can't close program either. I tried using a SwingWorker for the while which does not block the GUI but still playTurn() returns.

I have even tried creating a new thread where I call the method. The doesn't get blocked anymore but the method still returns.

Thread one = new Thread() {
                    public void run() {
                        playTurn(turn);
                    }
                };

FIXED: Placing the runnable up higher in the stack;

War es hilfreich?

Lösung

Your playTurn method runs the code on the EDT, cause of this line javax.swing.SwingUtilities.invokeLater(new Runnable() {, which makes your application GUI unresponsive as GUI-changing code must generally be run on the EDT. Since your buttons won't change from your GUI, once the loop starts, it might just loop forever.

By running the code in another Thread, you won't freeze your GUI. I'm guessing, since you don't provide much informations on the rest of your code, that you might have to change the way you handle things once your loop is done.

Edit from comments : Since you don't want playTurn to return, don't use a thread within it and make sure playTurn is not running on the EDT. Your playTurn method will return after creating and making a new Thread run the code.

You might want to try dong it like this :

Runnable code = new Runnable() {
  @Override
  public void run() {
    for (String turn : controller.getTurns()) {
      playTurn(turn);
    }
  }
};

if (!SwingUtilities.isEventDispatchThread()) {
  code.run();
} else {
  new Thread(code).start();
}

To make sure you don't run the code on the EDT. That way, playTurn doesn't return until the loop condition is met, the GUI stays responsive.

public void playTurn(String turn) {
  if (controller.givePlayers().contains(turn)) {
    while (!turnFinished) {
      if (!button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled() && !button1.isEnabled()) {
        turnFinished = true;
      }
    }
  } else {
    deletePlayer(turn);
  }
}

Doing this might have you change a few things more.

The idea is to make the call to a new Thread where you don't want it/need it to wait for the code being run in a new Thread to end to continue.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top