Если вы добавляете свой компонент в событие mouseClicked
, это, вероятно, подтвердит необходимость вызова, поскольку вы меняете контейнер (JFrame
). Кроме того, JFrame являются особенными: они имеют панель содержимого , и вы должны добавить компонент следующим образом:
frame.getContentPane().add(...);
В панели содержимого по умолчанию используется BorderLayout
.
Добавление компонента для каждого клика, вероятно, излишне, и у вас будут проблемы с макетом, если вы не установите его на null
(например, абсолютный макет) и не вызовете setBounds (x, y, 50, 50) для каждого круга .
Однако, поскольку вы переопределяете paintComponent
, вы можете напрямую рисовать овалы и не заботиться о компоновке или компонентах.
Добавьте компонент Circle
один раз с ограничениями BorderLayout.CENTER. Это обеспечит максимальный размер вашего Circle
.
* * * * * * MouseListener
должно быть на Кругу, и вам нужно сделать его фокусируемым (setFocus(true)
).
Каждый раз, когда мышь нажимается на Circle
, регистрируйте положение мыши в списке (например, List<Point>
), а затем вызывайте repaint:
circle.points.add(new Point(e.getX(), e.getY()); //
circle.repaint();
Каждый раз, когда вызывается paintComponent(Graphics)
, используйте список, чтобы нарисовать овалы в порядке их вызова.
@Override
protected void paintComponent(Graphics g) {
System.out.println("paint");
Graphics2D g2d = (Graphics2D) g;
super.paintComponent(g2d);
g2d.setColor(decodeCircleColor(circleColor));
// if you know lambda
points.forEach(p -> g2d.fillOval(p.x, p.y, 50, 50));
// or if you don't know lambda yet.
// for (Point p : points) g2d.fillOval(p.x, p.y, 50, 50));
}
Обратите внимание, что вы можете использовать Point или любой соответствующий класс (например, вы можете использовать конкретный объект, который будет хранить объект Paint
, такой как java.awt.Color
, для изменения цвета овала).