Есть 2 способа.
Либо есть класс Map, который является основным JPanel, чтобы поддерживать коллекцию юнитов, но сохранить класс Unit как не-Swing. Когда вызывается метод paint () карты, попросите каждый модуль перерисовать себя, вызвав метод в каждом видимом модуле. Модуль может быть унаследован от любого базового класса, например Rectangle, или какой-либо другой структуры данных, которую вы используете в программе. В этом случае класс Unit обрабатывает рисование и вычисления, а карта обрабатывает щелчки и события для каждого модуля. Он может передать сообщение в подразделение, если это необходимо; однако, если самому устройству не нужно знать об этих вещах, этот метод работает хорошо. Класс Unit легкий и экономичный. Вы также можете решить, знает ли Подразделение свою позицию на карте или нет.
Или иметь каждый юнит в качестве JComponent и обрабатывать его собственные события отдельно. Недостатком является то, что каждый экземпляр юнита создает кучу данных для его отрисовки. Таким образом, если у вас есть сотни юнитов, из которых нарисовано только несколько, этот способ неэффективен. Преимущество состоит в том, что каждый юнит может обрабатывать свои собственные события GUI без перевода и т. Д. Это предполагает также отображение 1: 1 реальных юнитов в игре и графических юнитов на экране. Также сложнее реализовать определенные обработчики событий в модуле, если ему нужно знать, что вокруг других модулей!
Третий и, возможно, лучший способ состоит в том, чтобы иметь класс модулей данных, содержащий игровую информацию о модуле, как в (1), но у которого есть метод для создания JComponent, когда это необходимо. Например, JComponent может быть внутренним классом в модуле - он может получить доступ к данным модуля. Это замечательно, если единицу измерения необходимо отображать в 2 местах (например, на 2 экранах или видах).
-
Приложение к адресным комментариям
Это верно, в (1) Карта (основной JPanel) реализует обработчик мыши и спрашивает каждый юнит по очереди, если он «попал». Это позволяет вам делать более сложные вещи, например, иметь 2 блока, накладывающихся друг на друга / друг на друга, и оба могут реагировать на щелчок.
Кроме того, например, они могут быть не прямоугольными или могут быть нарисованы с помощью альфа-канала (если Юниты были JComponents, они по умолчанию будут захватывать любое событие мыши по всему своему прямоугольнику). Если ваши юниты не перекрываются и находятся в своих собственных прямоугольниках, тогда достаточно собственного обработчика мыши JComponent.
Если вы используете подход (1), Карта может спросить каждый блок, содержит ли он точку, по которой щелкают, и Карта затем может обработать процесс «выбора». Помните, что подразделение само по себе не сможет определить, какие другие подразделения выбраны - выбор может включать отмену выбора другого подразделения. В этом случае операция выбора на самом деле является операцией Map, а не операцией Unit, хотя она также может изменить внешний вид или функцию Unit.
Если вы используете отдельные JComponents для Юнитов, вы можете переопределить «Содержит» (Точка), чтобы определить, попадет ли мышь в элемент, но это не позволит другим Юнитам также реагировать на щелчок. Но каждый юнит может «выбрать себя» (установить флаг, используемый при рисовании), а затем уведомить карту (он должен будет найти его с помощью getParent или с помощью предварительно заданного свойства).
Ключевыми вещами, которые вы должны знать, прежде чем принять решение об этом проекте, будет:
Вам когда-нибудь понадобится более одной панели «Карта» на игру?
Вам когда-нибудь понадобится больше объектов Юнитов, чем должно быть отображено?
Вам когда-нибудь нужно будет отображать юнит более одного раза?
Если ответы да, вы должны отделить классы «Данные» от классов «Просмотр», как предложено в 3.затем: Что нужно «сделать» Юниту и что ему нужно знать о Карте и других Юнитах, чтобы сделать это? например перемещение обычно выполняется классом Map в этой ситуации, так как это зависит от карты и других юнитов; рисование лучше всего выполнять модулем, потому что может быть много подтипов модуля с различными структурами данных, которые, возможно, должны быть нарисованы; Операции выбора юнитов, как вы указали, находятся где-то посередине. Если вы видите, как Swing реализует это (например, ButtonGroup, ListSelectionModel), само «выделение» может рассматриваться как отдельный класс.