, что сделаны определенные вычисления, и на экране динамически нарисованы круги (будь то больше, меньше, смещены влево или вправо и т. Д.).
Ну, вам нужно определить, что вы хотите, чтобы происходило при изменении размера кадра. Мы не можем сказать вам, что делать.
Однако, прежде чем беспокоиться о том, что вам нужно реструктурировать свои классы, чтобы сделать возможным динамическое рисование.
Я вижу следующие проблемыс основным кодом:
Забудьте о размере кадра. Этот размер не имеет отношения к пользовательской картине, которая будет выполнена в вашей CirclePanel. То есть размер CirclePanel НЕ совпадает с размером вашего фрейма, поскольку размер фрейма включает границы фрейма и строку заголовка. Ваша логика должна основываться на размере панели, а не на рамке.
При выполнении пользовательского рисования компонент также должен переопределить метод getPreferredSize()
, чтобы вернутьпредпочтительный размер компонента. Затем в своем коде вы добавляете панель к фрейму и затем вызываете метод pack()
для фрейма.
Вы вызываете свой класс CirclePanel, но расширяете JComponent. Почему? Дайте своему классу правильное имя. Если вы хотите расширить JComponent, тогда вызовите свой класс CircleComponent. Если вы хотите назвать свой класс CirclePanel, то расширьте JPanel. Но вы также должны понимать разницу между расширением JComponent и JPanel. Все компоненты Swing отвечают за очистку фона компонента ПЕРЕД выполнением рисования. JPanel делает это для вас автоматически, вы просто вызываете super.paintComponent (...) в начале. JComponent НЕ очищает фон, поэтому вы должны очистить его, установив цвет объекта Graphics, а затем вызовите fillRect (0, 0, getWidth (), getHeight ()) для рисования фона.
Объект Circle должен содержать всю информацию, необходимую для рисования. У вас уже есть значения x, y, radius. Я бы посоветовал вам также использовать свойство Color, чтобы каждый круг мог иметь свой цвет.
Затем объект круга должен знать, как рисовать себя, используя свои свойства. Поэтому у вашего класса Circle должен быть метод, скажем, draw(Graphics grapics)
. Затем вы используете свойства класса для рисования овала. Таким образом, это означает, что метод paintComponent () вызовет метод draw (...) класса Circle, и вы удалите метод drawOval (...), который у вас есть на данный момент.
Метод «получения» не принимает параметры. Если вы чувствуете, что другим классам нужно знать свойства x, y, radius, создайте методы getX (), getY () и getRadiout (). Я бы посоветовал вам не использовать методы get () / set ().
Я предлагаю вам сначала реализовать перечисленные выше рекомендации, прежде чем рисовать динамически.
Далее вам не нужно добавлять ComponentListener на панель. Вместо этого вам нужно добавить логику в метод paintComponent(...)
вашего класса CirclePanel. Метод paintComponent () будет вызываться автоматически каждый раз, когда изменяется размер панели. Основная логика заключается в определении «множителя», который будет использоваться при рисовании каждого круга.
Таким образом, вы можете использовать метод getPreferredSize()
, чтобы получить предпочтительную ширину, и вы можете использовать метод getWidth()
дляпанель, чтобы получить текущий размер. Таким образом, ваш множитель будет:
double multiplierX = getWidth() / getPreferredSize().x;
Теперь эту информацию необходимо передать в метод рисования (...) объектов Circle, чтобы сигнатура метода стала draw(Graphics g, double multiplierX)
. Когда вы вызываете метод drawOval(...)
, вы применяете множитель к параметру «x». Это должно привести к смещению кругов в горизонтальном направлении при изменении размера рамки.
Затем вы должны повторить вышеописанный шаг, чтобы множитель Y имел смещение кругов в вертикальном направлении.
ВыТогда нужно будет решить, как вы хотите повлиять на радиус?