мы создаем какой-то школьный проект на Java. Что мы пытаемся сделать:
есть JScrollPane как часть GUI, содержащая JLayeredPane (скажем, «MapPane»). MapPane содержит карту страны (внизу), которая является JLabel со значком. Это прекрасно работает, MapPane прокручивается, все в порядке.
Теперь мы хотим добавить еще несколько пользовательских графических элементов, расширяющих класс SpatialElement
каждый элемент расширяет класс SpatialElement (упрощенно):
public abstract class SpatialElement extends JComponent{
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// ...
// ...
paintElement(g2d);
}
public abstract void paintElement(Graphics2D g2d);
}
Так, например, элемент Polygon выглядит (упрощенно):
public class Polygon extends SpatialElement{ // SpatialElement extends JComponent
...
@Override
public void paintElement(Graphics2D g2d) {
// set color, stroke etc.
// ...
// prepare an array of coordinates and size (as required in drawPolygon method)
// draw fill
g2d.fillPolygon(x, y, size);
// draw polygon
g2d.drawPolygon(x, y, size);
}
}
Поэтому, когда пользователь добавляет новый графический элемент, вызывается метод addSpatialElement
(в MapPane
):
public class MapPane extends JLayeredPane implements MouseWheelListener, MouseInputListener, Observer{
//...
public void addSpatialElement(SpatialElement element) {
element.updateBounds(); // set bounds of newly created element
spatialElements.add(element); // local storage of created elements
add(element, JLayeredPane.DRAG_LAYER + getComponentCount()); // put the element into another (higher) layer
validate();
// ???
}
}
Надеюсь, код простой, но достаточно наглядный. Проблема заключается в том, что, хотя вновь созданный компонент добавляется в MapPane (расширенный JLayeredPane), элемент не будет рисовать. Сначала я подумал, что это вызвано неправильными границами (вычисляется в методе updateBounds), но они в порядке.
Если я напрямую вызываю element.repaintComponent(getGraphics())
после добавления его в MapPane, он закрашивает элемент, но после любого взаимодействия с MapPane (например, изменение размера окна и т. Д.) MapPane перерисовывается, и поэтому объект не будет перекрашивать.
Как заставить MapPane перерисовать все содержащиеся компоненты при изменении размера? Должен ли я переопределить метод paintComponent по умолчанию для MapPane (чтобы я перебрал объект и вызвал repaintComponent () для каждого из них)?
Или есть какое-нибудь лучшее, не очень хитрое решение, как это сделать?
Спасибо за ваш совет.