MVC много зрения и один контроллер - PullRequest
3 голосов
/ 17 февраля 2012

В моем приложении много представлений (подкомпонентов) и только один контроллер. Выбор некоторых параметров в одном представлении может изменить макет и количество компонентов в другом представлении. Контроллер инициализирует представление, которое, в свою очередь, создает все подкомпоненты.

В таком приложении контроллер должен иметь ссылку на все подкомпоненты? Как в слушателе в одном представлении вызывает контроллер для выполнения действия, а затем необходимо обновить другое представление. Я чувствую, что у контроллера не должно быть ссылки на все виды, но я не знаю, куда идти здесь. Пример из книги «Первые шаблоны проектирования в Head» имеет только один вид, поэтому я застрял.

++++++++++++++++++++++++

Подробнее. Игра, которую я пишу, - это игра в шашки (шашки). В одном сценарии, когда компьютер играет против самого себя, пользователь должен выбрать некоторые параметры перед началом игры. Одним из таких вариантов является выбор стратегии игры на определенные периоды в течение игры. Например, если на доске будет от 12 до 8 фигур, она будет атаковать больше, на доске от 8 до 4 фигур будет более оборонительной.

На данный момент игровой интерфейс структурирован так, что существует один общий JPanel (RightContainerFrame), который содержит другие JPanel; затем существует один JPanel (StartGamePanel), в котором пользователь может настроить игру. Существует также JTabbedPane (jTabbedPane1), который содержит вкладки. В настоящее время в StartGamePanel, когда пользователь выбирает определенную опцию в JComboBox, необходимо добавлять или удалять вкладки из jTabbedPane1.

В настоящее время я достигаю этого в StartGamePanel

RightContainerFrame.getInstance().generateAndDisplayPlayerTwoRangeTabs(numberOfRangeTabsNeeded);

Теперь я знаю, что все это неправильно, поскольку у меня есть одно представление, StartGamePanel напрямую изменяет другое представление JTabbedPane, вызывая метод в другом представлении контейнера RightContainerFrame.

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

Сначала я мог переместить метод jComboBox1ActionPerformed на контроллер. Это может либо обновить модель для jTabbedPane1. Или он может вызвать метод непосредственно в jTabbedPane1 для отображения необходимого количества вкладок.

Ответы [ 3 ]

3 голосов
/ 17 февраля 2012

Swing - это не настоящая архитектура MVC: это модель / (представление + контроллер) архитектура .Каждый JComponent является и представлением, и контроллером.

Вам необходимо определить методы обратного вызова (прослушиватели событий), которые вы связываете с каким-либо событием в компонентах.Существуют разные типы прослушивателей событий для разных типов событий на разных JComponents.

Вот пример, где прослушиватель событий регистрируется на кнопке, так что при нажатии он меняет текст в другом компоненте (myJLabel):

jButton1.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent event) {
        myJLabel1.setText("You just clicked a button.");
    }
}
// you can add other ActionListeners to the same jButton1

Вы можете иметь глобальныйконтроллер, который обрабатывает все события, но вам нужно будет зарегистрировать его как слушатель для каждого компонента.Когда глобальный контроллер получил event, он может запросить его, чтобы узнать, с какой кнопки он пришел, и соответственно изменить другие JComponent.Так что, да, вашему глобальному контроллеру потребуются ссылки на все JComponents, в дополнение к тому, что он будет зарегистрирован для всех них как слушатель.Глобальный контроллер должен был бы реализовать не только ActionListener, как описано выше, чтобы получать щелчки мыши, но также и все другие типы EventListener, необходимые для обработки всех других типов событий из других компонентов.

Возможно, это не такхорошая идея иметь глобальный контроллер, потому что он может оказаться очень большим классом.Достаточно просто позволить каждому JComponent зарегистрировать один (или несколько) прослушивателей событий, которые напрямую изменяют некоторые другие компоненты.

EDIT :
Я не уверенплохая идея иметь глобальный контроллер: у вас получается огромный класс, но по крайней мере вся логика обратного вызова находится в одном месте.

2 голосов
/ 17 февраля 2012

Пока я не знаю, как представления обновляют другие представления.

Этот простой пример иллюстрирует шаблон наблюдателя , который позволяет модели обновить представление в ответ на контроллер и просмотр действий. Этот более сложный пример показывает три представления прослушивания одной модели .

1 голос
/ 17 февраля 2012

Я, честно говоря, не могу четко понять ваш дизайн, но дизайн, который я выбрал бы в этом случае (предполагая, что мы говорим о богатых компонентных технологиях пользовательского интерфейса), заключается в том, чтобы View слушали шину событий и адаптировали своимакет по мотивам происходящих в автобусе событий.В этом контексте обработчики действий пользовательского интерфейса могут публиковать события в шине.Эффективно развязывает представления друг от друга и от контроллера.

Обновление: посмотрите здесь - то, что вещи Google имеют тенденцию быть немного занудным и чрезмерно продуманнымдля большинства задач с низким и средним уровнем сложности, но вы можете обрезать его под свои нужды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...