如何根据 JPanel 的内容找出未显示的首选尺寸?

发布于 2024-08-20 13:53:26 字数 367 浏览 3 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

酷到爆炸 2024-08-27 13:53:26

Suraj 和 willcodejavaforfood 让我走上了正轨。

检查 pack() 方法中实际执行的操作,我发现这主要是将当前大小设置为 getPreferredSize() 返回的大小。

由此,我设法做出这样的解决方案:

// Creating the panel
JPanel lPanel = new JPanel();
//lPanel.setSize(1000, 1000); //default size, not needed anymore
lPanel.setLayout(new BoxLayout(lPanel, BoxLayout.PAGE_AXIS));

//Adding the content
lPanel.add(new JLabel("Blah"));
// etc...

//Adjust the panel to its preferred size
lPanel.setSize(lPanel.getPreferredSize());

//Call the layout method 
//(this will adjust the content components to their correct size and position)
lPanel.doLayout();

此方法工作正常,并将面板及其内容调整为正确的大小(并以简单的方式回答我的问题:“如何找到首选大小? 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 by getPreferredSize().

From this, I managed to make such solution:

// Creating the panel
JPanel lPanel = new JPanel();
//lPanel.setSize(1000, 1000); //default size, not needed anymore
lPanel.setLayout(new BoxLayout(lPanel, BoxLayout.PAGE_AXIS));

//Adding the content
lPanel.add(new JLabel("Blah"));
// etc...

//Adjust the panel to its preferred size
lPanel.setSize(lPanel.getPreferredSize());

//Call the layout method 
//(this will adjust the content components to their correct size and position)
lPanel.doLayout();

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 calling doLayout(). As such, the panel can be set to its proper size before calling the layout method.

断肠人 2024-08-27 13:53:26

直接的答案是调用 窗口#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();

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文