更新 JPanel 图形时出现无限循环
因此,我使用 Grahics2D
在 JPanel
对象中绘制图形。
当我的图形大于窗口时,JPanel
被放置在 JScrollPane
中。
但是在绘制图形后,JPanel
的大小没有改变,并且我无法滚动查看图形的其余部分,因此我找到最低点和最左边的点,并在方法中手动设置大小进行绘图(方法称为 drawTrack()
)。
当我切换窗口或执行其他操作使 JPanel 再次绘制时,我的图形消失,因此我重写了 paint()
、repaint()
、validate ()
、invalidate()
方法,并在其中调用 drawTrack()
方法在重绘 JPanel 的每种可能情况下绘制图形。
问题是,当 JPanel 调用执行重绘的方法之一时,我会在其中调用 drawTrack() ,在重绘图形后手动设置大小,以便我可以滚动 JScrollPane
并查看我的整个图形。但是当我在 JPanel 上调用 setSize()
方法时,它会再次重绘,这意味着调用 drawTrack()
等等。
出现滚动条是因为尺寸正确,但它会创建一个无限循环,一遍又一遍地重绘我的图形。如果我不调用 setSize()
方法,我的 JPanel
将获得默认大小,以便它可以适合 JScrollPane
的视口,从而我无法滚动查看我的图形。
有什么建议吗?
So, I am drawing a graphic in a JPanel
object using Grahics2D
.
The JPanel
is placed in a JScrollPane
for the cases when my graphic is bigger than the window.
But after I draw my graphic the JPanel
's size does not change and I cannot scroll to see the rest of my graphic, so I locate the lowest and most left points and set the size manually in the method that does the drawing (method is called drawTrack()
).
When I switch windows or do something else that makes the JPanel to be drawn again, my graphic disappears, so I rewrote paint()
, repaint()
, validate()
, invalidate()
methods and in there I invoke the drawTrack()
method to draw my graphic on every possible case of redrawing the JPanel.
The problem is that when the JPanel
invokes one of the methods that do the redrawing I invoke drawTrack()
in them, which after redrawing my graphic sets the size manually so that I can scroll the JScrollPane
and see my whole graphic. But when I invoke setSize()
method on the JPanel that makes it to be redrawn again, which means to invoke drawTrack()
and so on and so on.
The scroll bars appear because the size is correct but it creates an infinite loop that redraws my graphic over and over. And if I don't invoke the setSize()
method my JPanel
gets default size so it can fit in the JScrollPane
's viewport and thus I cannot scroll it to see my graphic.
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当您调整 JPanel 的大小时,您会刺激重新绘制,因此,如果您更改 Paint 或 PaintComponent 方法或在这两种方法中调用的方法中的大小,对我来说,您有导致无限循环的风险,这是有道理的。
解决方案:不要在paint或paintComponent方法中调整任何内容的大小。这个方法只是为了绘画而已。相反,如果您想设置 JPanel 的大小,请重写其 getPreferredSize() 方法。
这是一个“多彩”的例子:
When you resize a JPanel you stimulate a repaint, and so if you change the size in a paint or paintComponent method or a method called in either of these methods, it makes sense to me that you are at risk of causing an infinite loop.
Solution: Don't resize anything in a paint or paintComponent method. That method is just for painting and nothing else. Instead if you want to set the size of your JPanel, override its getPreferredSize() method.
Here's a "colorful" example:
这是不必要的。自定义绘画代码只能从paintComponent() 方法中调用。
This is unnecessary. The custom painting code should only ever be invoked from the paintComponent() method.
面临类似的问题:JPanel 的paintComponent 方法调用了其他“方法”,涉及Graphics 的更改,因此调用另一个paintComponent 循环。
我还没有找到将这些“方法”移到 PaintComponent 之外的结构方法,但找到了以下解决方案:用 if 子句包围这些“方法”,并用布尔标志打破循环:
Faced similar problem: JPanel's paintComponent method called other "methods", that involved changes in Graphics and therefore called for another paintComponent loop.
I haven't found a structural way to move these "methods" outside paintComponent, but found the following solution: surround these "methods" with if clause and break the loop with a boolean flag: