How to properly wait until ActionListener is executed?

寵の児 提交于 2019-12-24 15:07:21

问题


I have a simple, variably sized tic-tac-toe App that works differently on different machines. On my laptop it works like I want it to and on my desktop, it gets stuck in the ButtonListener class that implements ActionListener. I'm pretty sure this is because of the way I am waiting for a action to be performed, using a while loop. Here is the offending code snippet.

public void playOneTurn(int player) {
    waiting = true;
    while (waiting) {
        // Do nothing, touchEvent will change waiting.
    }
}

I meant for this method to simply wait for a valid spot to be selected and for waiting to be flipped in the ButtonListener:

    class ButtonListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("TOUCHEVENT");

        for (i = 0; i < size; i++)
            for (j = 0; j < size; j++)
                if (e.getSource() == cells[i][j]) {
                    if (model[i][j] == 'e') {
                        cells[i][j].setText("");
                        currentSpot[0] = i;
                        currentSpot[1] = j;
                        if (count % 2 == 0) {
                            cells[i][j].setBackground(Color.GREEN);
                            cells[i][j].setIcon(X_MARK);
                            model[i][j] = 'x';
                            count++;
                            waiting = false;
                        } else {
                            cells[i][j].setBackground(Color.CYAN);
                            cells[i][j].setIcon(O_MARK);
                            model[i][j] = 'o';
                            count++;
                            waiting = false;

                        }

                    } else {
                        System.out.println("Hey, you can't move there silly!");
                    }
                }
    }
}

I know nothing about threads but I believe that the ButtonListener is starting a thread, and because of the way I'm waiting on it, with the while loop, the thread is never stopped to let the rest of my code run on certain machines.

Is my error in using the while loop to wait on an Event to flip a boolean, and if so, how would I properly wait for it?


回答1:


Do not simply use while(true) loop. It will take up your CPU usage. Use synchronization instead. Create a private final Object and call wait() on it. Prior to this send a reference of this object to the MessageListener. When your operation in MessageListener is completed you can call notify() on it.

Also take care of Spurious wakeups.




回答2:


You should redesign your application. There is no need to wait at all. The entire state of your application will not change unless there is some event (i.e. user input) which triggers such a change. That’s especially true for a tic-tac-toe game. The condition you want to wait for cannot become true unless some user input changed the state in way that allows it. Therefore you can check for the condition inside the listener at places where the condition could have become true. And then react on it immediately.

Therefore you should implement listeners which react on events, change the state of your application and return. The next state transition will happen when the next event occurs, not a single CPU cycle before that. If you want to do changes independent of user generated events, i.e. animations, use a Timer which will generate appropriate events.



来源:https://stackoverflow.com/questions/21874923/how-to-properly-wait-until-actionlistener-is-executed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!