如何根据 JPanel 的内容找出未显示的首选尺寸?
我正在使用 JPanel(内部有多个标签)在图表上添加动态信息。这个面板是动态创建的,在我用它绘制之前它是不可见的。
为此,我使用 BufferedImage,并且遵循与此其他问题。只要我指定所有尺寸(面板及其组件),它就可以很好地工作。
就像在所提到的问题的评论中所问的那样,我如何确定该面板的最佳大小?如果该面板以常规框架/布局设置显示,则将执行相同的操作。
就我而言,如何在某种程度上“打包”该面板,使其大小及其内容的大小设置为最佳(然后由标签的大小决定)?
I am using a JPanel (with several labels inside) to add a dynamic information on a graph. This panel is dynamically created, it is not visible before I use it to draw.
For this, I am using a BufferedImage, and I follow approximately the same steps as described on this other question. It works good, as long as I specify all sizes (the panel, and its components).
Like asked as well in comments of the referred question, how can I determine the optimal size of this panel? The same operation would be done if this panel was displayed in a regular frame/layout setting.
In my case, how can I "pack", in a way, this panel, so that its size, and size of its content are set to the optimal (determined by the size of labels, then)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Suraj 和 willcodejavaforfood 让我走上了正轨。
检查
pack()
方法中实际执行的操作,我发现这主要是将当前大小设置为getPreferredSize()
返回的大小。由此,我设法做出这样的解决方案:
此方法工作正常,并将面板及其内容调整为正确的大小(并以简单的方式回答我的问题:“如何找到首选大小? getPreferredSize() ”)。
但是,它需要将初始大小设置为足够大的大小,以便内容适合,否则它们不会放在布局上。这有点可惜,而且不是真正的“干净”,但我现在找不到办法避免这种情况。编辑: 实际上,默认大小不是必需的,因为即使在调用 doLayout() 之前,
getPreferredSize()
也会返回正确的值。因此,在调用布局方法之前,可以将面板设置为其适当的大小。Suraj and willcodejavaforfood put me on the good track.
Checking what is actually done in a
pack()
method, I see that this is mostly setting the current size to the one returned bygetPreferredSize()
.From this, I managed to make such solution:
This method works correctly, and adjusts the panel and its content to the correct size (and answers my question in a simplistic way: "how to find the preferred size?
getPreferredSize()
").However, it requires to set the initial size to a large enough size, so that the content fits in, or they won't be put on the layout. This is a bit pity, and not really "clean", but I can't find a way to avoid that, for now.Edit: Actually, the default size was not necessary, because
getPreferredSize()
returns the correct value, even before callingdoLayout()
. As such, the panel can be set to its proper size before calling the layout method.直接的答案是调用 窗口#pack()。此方法将自动将所有底层子容器的大小设置为他们的首选大小(当然这取决于子容器的布局,例如 BorderLayout 并不关心首选大小)。
因此,只要您设置了子组件的首选尺寸(或最小/最大尺寸,如果布局类似于 BorderLayout), pack() 方法将满足您的需要。
[更新]
一种方法是添加 HierarchyListener 到您的 jpanel 并检查 HierarchyEvent#DISPLAYABILITY_CHANGED 事件。当您的面板准备好显示(并且父级可用)时,将调用此事件,此时您可以执行以下操作:
SwingUtilities#getWindowAncestor(myPanel).pack();
The direct answer is to call Window#pack(). This method will automatically set the size of all underlying children to thier preferred sizes(ofcourse this depends on layouts of child containers, for e.g. BorderLayout doesent give a damn about preffered sizes).
So as long as you have set preferred sizes(or min/max sizes in case layouts are like BorderLayout) of your child components, pack() method will be all you need.
[UPDATE]
One way is to do is add a HierarchyListener to your jpanel and check for HierarchyEvent#DISPLAYABILITY_CHANGED events. This event is called when your panel is realized that is ready to be shown(and a parent is available), at this moment you can do:
SwingUtilities#getWindowAncestor(myPanel).pack();