JPanel 在另一个 JPanel 中的重绘问题
我正在这个 JPanel
内绘制形状,它也在另一个主 JPanel
内。在repaint()
中,它只绘制形状一毫秒,然后它们就消失了。它们不会保持涂漆状态,为什么?
我的 PaintComponent 方法是这样的
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < reportElements.size(); i++) {
this.reportElements.get(i).display((Graphics2D) pageComponents.get(i).getGraphics());
}
}
当父级是启用了 setEditable() 的 JEditorPane
时,它可以工作,我们可以看到形状,但是当它是一个 JPanel
,一毫秒后我看到的只是空面板。
I'm drawing shapes inside this JPanel
, which is also inside another main JPanel
. At repaint()
it only draws the shapes for one millisecond and then they disappear. They don't stay painted, why?
My paintComponent
method is something like this
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (int i = 0; i < reportElements.size(); i++) {
this.reportElements.get(i).display((Graphics2D) pageComponents.get(i).getGraphics());
}
}
When the parent is a JEditorPane
with setEditable()
enabled, it works and we can see the shapes but when it's a JPanel
, after a millisecond all I see is empty panels.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您应该绘制 JPanel 的 Graphics 对象,使其永久...在您的示例中,这就是
Graphics g
...you should paint to the Graphics object of the JPanel for it to be permanent... In your example, that is the
Graphics g
...我不确定我是否理解你的评论。您的主面板应包含子面板。应使用布局管理器将子面板添加到主面板。然后,当 Swing 决定重新绘制主面板时,它也会重新绘制所有子面板,而子面板又会重新绘制其中的形状。
对于其价值自定义绘画方法有一个可行的示例在面板上绘制形状。
I'm not sure I undertand your comment. Your main panel should contain child panels. The child panels should be added to the main panel using a layout manager. Then when Swing decides to repaint the main panel, it will also repaint all the child panels and in turn the child panels will repaint there shapes.
For what its worth Custom Painting Approaches has a working example of drawing shapes on a panel.
ultrajohn 完全正确。您需要使用已传递的
Graphics
。请继续阅读以了解原因...Java 1.6 引入了支持优化重绘请求的
RepaintManager
。它对绘画有一些微妙的影响。在本例中,您正在使用多个 Graphics2D 对象:传递到
paintComponent
的g
以及getGraphics
调用返回的值。重绘管理器已将要绘制的
g
交给您。注意:这不会在屏幕上绘制,而是在临时缓冲区上绘制(假设默认双缓冲)。在
paintComponent
调用中,您将绘制从各个组件的getGraphics
获取的图形。这是绕过重绘管理器并直接绘制到无缓冲的显示。当
paintChildren
返回时,RepaintManager
开始处理双缓冲区的更新。它在显示的缓冲区上绘制空白临时缓冲区,有效地擦除通过从 getGraphics 获取的图形对象绘制的内容ultrajohn is dead on. You need to use the
Graphics
you have been passed. Read on for the why...Java 1.6 introduced the
RepaintManager
that supports the optimizing of repaint requests. It has some subtle effects on painting.In this case, you're working with multiple Graphics2D objects: the
g
passed intopaintComponent
and the value returned by thegetGraphics
call.The repaint manager has handed you
g
on which to paint. Note: this does not paint on the screen, but on a temporary buffer (assuming the default double buffering).In the
paintComponent
call you are painting to the graphics obtained fromgetGraphics
of the various components. This is bypassing the repaint manager and painting directly to the unbuffered display.When
paintChildren
returns, theRepaintManager
kicks in to handle updating the double buffer. It paints the blank temporary buffer over the displayed buffer, effectively erasing what was painted through the graphics object obtained fromgetGraphics
可能是
paintChildren
或paintBorder
过度绘制了您在方法中绘制的任何内容。也许尝试重写paint
。在那里,您可以完全控制在组件上绘制的内容,并且您可以自己决定是否进一步调用paintComponent
、paintChildren
或paintBorder
全部。It might be that
paintChildren
orpaintBorder
overdraws whatever you've drawn in your method. Perhaps try overridingpaint
instead. There you have full control over what will be painted on the component, and you can decide yourself whether to further callpaintComponent
,paintChildren
orpaintBorder
at all.