Вопрос широкий, а ответ сложный.
По сути, вы хотите провести некоторое исследование таких понятий, как «разделение обязанностей» и «разделение кода».
Идея состоит в том,что вы нарушаете свои функциональные требования, чтобы ваши объекты выполняли одну специализированную работу.Вы также «разъединяете» код, чтобы изменение реализации одной части не оказывало негативного влияния на другие части программы.Обычно это достигается за счет использования интерфейсов.
Вы также захотите исследовать концепцию «модель-представление-контроллер», где под «данными» или «состоянием» моделируется один или несколько классов., но полностью не зависит от пользовательского интерфейса.Пользовательский интерфейс затем может «визуализировать» модель так, как он считает нужным.
Таким образом, «представление» (взаимодействующее с контроллером) может изменить состояние (или отреагировать на изменение).в состоянии) модели, что облегчает управление (не серьезно, это так)
Code Review ...
This ...
static JPanel container = new JPanel(new GridLayout(currentHeight, currentWidth), true);
isопасная и плохая идея.Это аннулирует концепцию инкапсуляции и позволяет любому создавать новый экземпляр container
в любое время без уведомления, что отсоединит его от того, что ранее использовала программа.На самом деле, вы действительно делаете это.
static
не ваш друг.При правильном использовании это полезно, но при таком способе это просто плохая идея, и ее следует избегать.
Вместо этого следует отдавать предпочтение «внедрению зависимостей», когда передаются «элементы», на которые опирается любой объектк нему.
Я бы избегал таких вещей, как ...
this.setSize(800, 600);
int frameWidth = this.getSize().width;
int frameHeight = this.getSize().height;
this.setLocation((width - frameWidth) / 2, (height - frameHeight) / 2);
Окна - это сложные компоненты, которые также содержат декорации окон, которые переносятся по содержимому.Это означает, что доступное пространство для содержимого составляет window size - window decorations
.Вместо.Вы должны полагаться на API менеджера компоновки, чтобы обеспечить соответствующие подсказки по размерам и pack
фрейм.
В большинстве современных ОС у вас есть «другие» системные элементы, что, опять же, уменьшает объем доступного пространства наэкран (доки, панели задач, другие интересные вещи).Вместо этого вы можете использовать setLocationRelativeTo(null)
для более надежного центрирования окна на экране.
Вместо setIconImage
следует использовать Window#setIconImages(List)
, что позволяет вам передаватьколичество изображений, которые могут использоваться API для представления приложения в разных местах, для которых требуются изображения с различным разрешением.
Не уверен, что ...
new Map(currentMapType, currentWidth, currentHeight, false);
, но это не очень помогает.
Если вы обнаружите, что просто создаете экземпляр класса без фактической поддержки ссылки на него, то это, вероятно, хороший признак плохого дизайна.
Ваш класс Map
вызывает кучувопросы, на которые нелегко ответить.Меня это беспокоит, что класс Map
изменяет состояние родительского класса и вместо этого выкрикивает «внедрение зависимостей».
Этого ...
mapPanel[i][j].setPreferredSize(new Dimension(height / 12, height / 12));
лучше избегать,Вы должны предпочесть переопределение getPreferredSize
, и оно должно просто возвращать «желаемый» размер, который затем может использоваться такими вещами, как GridLayout
, для более эффективного размещения компонента.
Это затем приводит к «разделениюобязанность".В этом разделе предполагается, что у вас должен быть класс «плитки», который будет самостоятельно управляться и отвечать за один элемент из модели.
В обработке событий мыши существует ряд ошибок, которые могут возникнуть ...
@Override
public void mouseEntered(MouseEvent e) {
super.mouseEntered(e);
JPanel parent = (JPanel) e.getSource();
new colorListener(parent, Color.LIGHT_GRAY);
parent.revalidate();
}
Вы не должны вызывать super.mouseXxx(e)
на одном из заданий этих методов, чтобы вызвать делегата MouseListener
s, так что запутайтесь прямо здесь.
Вы можете более легко использоватьe.getComponent()
, чтобы получить ссылку на компонент, который сгенерировал событие, но если панель была автономной единицей работы (т.е. Tile
) и MouseListener
анонимным или внутренним классом, вы могли бы отказаться отприведение в целом.
new colorListener(parent, Color.LIGHT_GRAY);
пугает меня, так как он устанавливает кучу объектов со строгими ссылками, которые не могут быть легко разыменованы, и при этом у меня нет четких намерений.
parent.revalidate();
не делает то, что, как вы думаете, делает.
revalidate
генерирует новый проход макета, то, что вы, кажется, хотите, это repaint
.
Эти...
container.setPreferredSize(containerSize);
container.setBounds(height / 4, height / 4, containerSize.width, containerSize.height);
- это просто плохие идеи.Позвольте содержимому контейнера вместе с менеджером макета разобраться.
Итак, краткий ответ: у вас осталось много исследований, таких как:
- Шаблоны проектирования ОО
- Передовой опыт ОО, включая «разделение обязанностей», «разделение кода» и, в более общем смысле, «внедрение зависимостей»
- Model-View-Controller, кодирование в интерфейсвместо реализации
просто назвать несколько