自定义组件不会在 JLayeredPane 中绘制
我们正在用 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< /code> 被调用(在
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 方法中计算)引起的,但它们没问题。
如果我在将元素添加到 MapPane 后直接调用 element.repaintComponent(getGraphics())
,它会绘制该元素,但在与 MapPane 进行任何交互(例如调整窗口大小等)之后,MapPane被重新绘制,因此该对象不会重新绘制。
如何强制 MapPane 在调整大小时重新绘制所有包含的组件?我是否必须重写 MapPane 的默认 PaintComponent 方法(这样我就可以迭代该对象并在每个对象上调用 repaintComponent() )?
或者有一些更好的、不那么棘手的解决方案如何做到这一点?
谢谢你的建议。
we're creating some school project in Java. What are we trying to do:
there is JScrollPane as part of the GUI, containing JLayeredPane (let's say "MapPane"). MapPane contains the map of the country (on the bottom), which is JLabel with icon. This works great, MapPane is scrollable, everything ok.
Now, we want to add some more custom graphical elements extending class SpatialElement
every element extends class SpatialElement (simplified):
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);
}
So for example element Polygon looks like (simplified):
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);
}
}
So when user adds a new graphical element, a method addSpatialElement
is called (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();
// ???
}
}
I hope the code is simple but descriptive enough. The problem is, that even though newly created component is added into the MapPane (extended JLayeredPane), the element won't paint. First I thought that it's caused by wrong boundaries (computed in updateBounds method) but they are ok.
If I directly call element.repaintComponent(getGraphics())
after adding it into the MapPane, it paints the element, but after any interaction with the MapPane (e.g. resize of the window, etc.) the MapPane is repainted and so the object won't repaint.
How to force the MapPane to repaint all containing components on resize? Do I have to override default paintComponent method of the MapPane (so I would iterate through the object and call repaintComponent() on each of them)?
Or is there some better, not so tricky solution how to do it?
Thanks for your advice.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论