Ожидание действий пользователя в цикле while - JAVA - PullRequest
0 голосов
/ 29 мая 2011

Я пишу заявку Реверси. Я реализовал класс менеджера поворотов, но у меня небольшая проблема в цикле while.

Это мой фрагмент:

while (!table.isFull() || passFlag != 2) {
    if (player1.isActive()) {
        for (int i = 0; i < table.getSize(); i++) {
            for (int j = 0; j < table.getSize(); j++) {
                table.getField(i, j).addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                if (e.getSource() instanceof Field) {
                                    ((Field) e.getSource()).changeToBlack();
                                }
                            }
                        });
            }
        }
    }
    if (player2.isActive()) {
        for (int i = 0; i < table.getSize(); i++) {
            for (int j = 0; j < table.getSize(); j++) {
                table.getField(i, j).addActionListener(new ActionListener() {
                            public void actionPerformed(ActionEvent e) {
                                if (e.getSource() instanceof Field) {
                                    ((Field) e.getSource()).changeToWhite();
                                }
                            }
                        });
            }
        }
    }
    sentinel.changeActivePlayer(player1, player2);

Таблица представляет собой сетку кнопок, а поля - кнопки. Цикл не ждет взаимодействия с игроком. Как я могу реализовать код так, чтобы он ждал щелчка мышью пользователя?

Это полный код этого класса

package Core;

import GUILayer.Field;
import GUILayer.MainFrame;
import elements.Player;
import elements.Table;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TurnManager {

    int passFlag = 0;
    int TurnFlag = 0;
    Sentinel sentinel = new Sentinel();

    public TurnManager() {
    }

    public void manage(MainFrame mainframe, Table table, Player player1, Player player2) {

        while (!table.isFull() || passFlag != 2) {
            if (player1.isActive()) {
                for (int i = 0; i < table.getSize(); i++) {
                    for (int j = 0; j < table.getSize(); j++) {
                        table.getField(i, j).addActionListener(
                                new ActionListener() {

                                    public void actionPerformed(ActionEvent e) {
                                        if (e.getSource() instanceof Field) {
                                            ((Field) e.getSource()).changeToBlack();
                                        }
                                    }
                                });
                    }
                }
            }
            if (player2.isActive()) {
                for (int i = 0; i < table.getSize(); i++) {
                    for (int j = 0; j < table.getSize(); j++) {
                        table.getField(i, j).addActionListener(
                                new ActionListener() {

                                    public void actionPerformed(ActionEvent e) {
                                        if (e.getSource() instanceof Field) {
                                            ((Field) e.getSource()).changeToWhite();
                                        }
                                    }
                                });
                    }
                }
            }
            sentinel.changeActivePlayer(player1, player2);
        }
    }
}

Ответы [ 3 ]

4 голосов
/ 29 мая 2011

Я согласен с комментарием Говардса ... это выглядит очень неправильно. Использование слушателей и событий означает, что вам (в большинстве случаев) не нужно использовать цикл событий самостоятельно.

Попробуйте следующее: Создайте класс, который содержит вашу доску. Доска знает, какой цвет имеет каждое поле (и все остальное, что нужно знать). Когда ваш графический интерфейс инициализирован, вы создаете single EventListener, который вызывает некоторый метод объекта Board. Этот метод передается по полю, по которому щелкнули (я полагаю, по нему щелкнули, или я ошибаюсь?). Вы храните ссылку на этот EventListener в переменной. Затем вы перебираете каждый for и столбец и присоединяете этот слушатель к каждому полю. Затем вы отображаете графический интерфейс.

Позвольте уточнить: все это делается во время инициализации.

0 голосов
/ 29 мая 2011

Это не полное решение, но ваш код должен выглядеть примерно так. Я думаю, что это хорошая отправная точка для совместной работы. Надеюсь, это поможет.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class TurnManager implements ActionListener{

    int passFlag = 0;
    int TurnFlag = 0;
    Sentinel sentinel = new Sentinel();
    Player player1,player2;


    public TurnManager(MainFrame mainframe, Table table, Player p1, Player p2) {
        player1 = p1;
        player2 = p2;
        for (int i = 0; i < table.getSize(); i++) {
            for (int j = 0; j < table.getSize(); j++) {
                table.getField(i, j).addActionListener(this);
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof Field) {
            Field field = ((Field) e.getSource());
            //implement logic here, for example:
            if (table.isFull())
                throw new RuntimeException("Table full! Stop! STOP!");

            if (player1.isActive())
                field.changeToBlack();
            if (player2.isActive())
                field.changeToBlack();
        }
    }
}
0 голосов
/ 29 мая 2011

Несколько предложений:

  • Как уже отмечалось, вам не нужны ваши циклы while, и их наличие (даже если они работали) делает ваш код не управляемым событиями.
  • Вы хотите отделить модель от вида.Модель - которая должна быть довольно неосведомлена о представлении - будет знать, чья это очередь.Он будет иметь нестатическое поле, которое сообщит ему, чей это оборот, перечисление хорошо работает для этого, и когда пришло время менять термины, значение этого поля изменяется.
  • Каждая ячейка будет иметьподключен слушатель (или «элемент управления»), вероятно, тот же слушатель (согласно посту Мартина - +1 для него), и единственной задачей слушателя будет сообщить модели, в какую ячейку щелкнули, информацию, которую можно получить, вызвав getSourceна параметр события слушателя.Если слушатель является ActionListener, то событие, о котором я говорю, будет объектом ActionEvent, который передается в метод actionPerformed слушателя.
  • Затем модель решает, что делать с информацией, если что-либо, на основев какой ячейке была нажата и чья это очередь.
  • Представление (GUI) будет прослушивать изменения модели, возможно, с помощью PropertyChangeListener или с другим слушателем вашего собственного создания, и будет изменять свое отображение на основесостояние модели.
...