我们正在用 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
会调用一个方法(in 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 在调整大小时重新绘制所有包含的组件?我是否必须覆盖 MapPane 的默认 paintComponent 方法(所以我将遍历对象并在每个对象上调用 repaintComponent() )?
还是有一些更好的,不是那么棘手的解决方案怎么做?
谢谢你的建议。