Java Swing много JPanels в JFrame - геттеры или все в одном?

Я хотел бы спросить вас об одном техническом аспекте создания GUI в Swing. Предположим, у меня есть JFrame или JDialog (неважно) с контентом, организованным во многих JPanels (настройки, действия, отображение данных, диаграммы и т. д.) - все в одном фрейме.

Например: здесь

Что я сейчас делаю, так это определяю все компоненты в одном файле (назовем его MainPanel.java) и организую их в JPanels. A иметь отдельные методы для организации каждой панели

private void organizePanels() {
  pnlSettings = createPnlSettings();
  pnlActions = createPnlActions();
  pnlChart = createPnlChart();
  // ...
}

Каждый метод отвечает за настройку макета JPanel, организацию компонентов внутри него и т. д. Когда у меня есть 3-4 несложных панели, это имеет смысл (я имею в виду вполне читаемый). Но если я создам более сложную структуру, она станет небольшим кошмаром для обслуживания (или хорошей отправной точкой для этого).

Вот почему я хочу использовать такой подход: - Для каждого JPanel создайте отдельный класс - Каждый класс должен иметь средства доступа к своим внутренним компонентам (нажатие JButton в JPanel A должно привести к обновлению JCombo в другом JPanel). - Связь между панелями должна каким-то образом обеспечиваться MainPanel.

Итак, в mainPanel у меня будут ссылки только на JPanel, а не на компоненты внутри них. Доступ к определенным данным будет немного дольше (pnlActions.getSaveButton.setEnabled(true) вместо btnSave.setEnabled(true), но это, вероятно, естественное следствие. Я также могу сделать все компоненты в JPanel общедоступными.

Считаете ли вы такой подход правильным? Считаете ли вы, что я должен использовать второй подход все время или, может быть, мой первый подход подходит для не очень сложных структур?

Какой у вас опыт?


person guitar_freak    schedule 13.10.2013    source источник


Ответы (2)


Как и многие другие вещи в дизайне приложений с графическим интерфейсом, выбор лучшего пути является вопросом компромиссов, которые в конечном итоге зависят от самого приложения. Не существует правильного ответа, применимого ко многим приложениям.

Ваш способ будет работать и может быть лучшим в некоторых ситуациях. Однако он распространяет знания об организации ваших панелей графического интерфейса на несколько классов, и это может сделать обслуживание более сложным, чем необходимо. Если вы позже захотите переместить некоторые кнопки или группы кнопок на другую панель по какой-либо причине, тогда доступ к данным изменится, а это означает, что вам придется изменить код в любых местах доступа к данным, а также где находятся кнопки.

Вы также можете разработать класс, который содержит только данные для панели, гарантируя, что в нем нет никаких зависимостей пользовательского интерфейса. Ни Swing, ни какой-либо другой пакет пользовательского интерфейса не должны появляться в списке импорта, и если вы хотите использовать этот класс, скажем, в приложении SWT, Spring MVC или Windows, он должен работать там без изменений. Затем предоставьте ссылку на одноэлементный экземпляр этого класса каждой из ваших панелей и позвольте им получать и устанавливать значения по мере необходимости. Это позволяет вам изменять пользовательский интерфейс любым удобным для вас способом, не меняя способ доступа к данным.

Этот метод предполагает, что эта «модель данных» для данного фрейма/диалога не настолько сложна, чтобы сам класс для ее обработки был чрезмерно сложным. Для такого сложного фрейма вы можете рассмотреть общую модель, разделенную на разделы, учитывая, что доступ к разным частям модели требуется только из определенных частей пользовательского интерфейса, и разделение доступа между этими разделами.

person arcy    schedule 13.10.2013

Я думаю, вы на правильном пути. Я бы даже пошел дальше, введя класс обработчика панели (статический или нет). Таким образом, вы четко отделяете компоненты GUI (включая сам JFrame) от его внутреннего управления. Каким-то образом зарегистрируйте свои панели с помощью общедоступного метода в вашем обработчике панелей. Если в одной панели происходит что-то, что влияет на другую, вы позволяете панели связаться с обработчиком, как вы уже запланировали. Все панели имеют соответствующий интерфейс, который определяет, как обработчик может манипулировать ими. Этот концептуальный дизайн вполне применим для больших приложений, потому что обработчик суммирует все возможные взаимодействия, которые могут быть вызваны, вместо того, чтобы «прятать» функциональные возможности где-то в куче классов панелей.

Вы даже можете улучшить этот концептуальный дизайн, позволив всем панелям наследовать методы или переменные, которые они используют совместно. Это сокращает время и усилия для внесения некоторых изменений в код. Если вы хотите использовать более параллельное программирование, класс-обработчик позволяет вам создать запрос для всего, что нужно сделать. Вы просто позволяете панелям добавлять задания в запрос, а обработчик выполняет задания и впоследствии удаляет их из запроса.

person Florian R. Klein    schedule 13.10.2013