简体   繁体   English

内部组件的 JPanel 大小

[英]JPanel size by inner components

Is it possible to tell JPanel to set its size to fit all components that it contains?是否可以告诉 JPanel 设置其大小以适合它包含的所有组件? Something like pack() for JFrame.类似于 JFrame 的pack()类的东西。

edit: The trick with preferredSize didn't help.编辑:首选大小的技巧没有帮助。 I've got JSplitPane, where in one part there is GridBagLayout with many labels (see screenshot) and labels overlap each other.我有 JSplitPane,其中的一部分是带有许多标签的 GridBagLayout(见屏幕截图)并且标签彼此重叠。

screenshot http://foto.darth.cz/pictures/screen.png截图 http://foto.darth.cz/pictures/screen.png

After looking at the source code for pack() , I came up with:查看pack()的源代码后,我想出了:

    panel.setPreferredSize(panel.getPreferredSize());

This forces the panel to recalculate its preferred size based on the preferred sizes of its subcomponenents.这会强制面板根据其子组件的首选尺寸重新计算其首选尺寸。

You may or may not have to call validate() afterward;之后您可能需要也可能不需要调用validate() in my tiny example, it seemed to make no difference, but the Javadoc says:在我的小例子中,它似乎没有区别,但 Javadoc 说:

The validate method is used to cause a container to lay out its subcomponents again. validate方法用于使容器重新布置其子组件。 It should be invoked when this container's subcomponents are modified (added to or removed from the container, or layout-related information changed) after the container has been displayed.当该容器的子组件在显示后被修改(添加到容器中或从容器中删除,或更改布局相关信息)时,应该调用它。

So I guess it depends on why you're having to repack your JPanel .所以我想这取决于你为什么要重新打包你的JPanel

By default Container s have a preferred size that matches the preferred layout size given by the container.默认情况下, Container具有与容器给出的首选布局大小相匹配的首选大小。 So literally all you have to do is:所以实际上你所要做的就是:

panel.setSize(panel.getPreferredSize());

Presumably you are doing something odd with the parent to stop the parent's layout manager doing the equivalent of this.据推测,您正在与父级做一些奇怪的事情,以阻止父级的布局管理器执行与此等效的操作。

maybe you can do something like that by removing from your panel也许你可以通过从面板上移除来做类似的事情

setResizable(false); setResizable(false);

I had a similar issue using Netbeans GUI Builder .我在使用Netbeans GUI Builder 时遇到了类似的问题。 My inner panels were getting weird sizes;我的内面板尺寸越来越奇怪; I was trying to adjust the minimum and preferred sizes manually, which was a frustrating exercise.我试图手动调整最小和首选尺寸,这是一个令人沮丧的练习。

The problem was solved when I reset all the minimum and preferred sizes back to default (In Netbeans GUI Builder: right click JPanel component -> Properties -> preferredSize -> Reset to Default).当我将所有最小和首选大小重置为默认值时,问题解决(在 Netbeans GUI Builder 中:右键单击 JPanel 组件 -> 属性 -> preferredSize -> 重置为默认值)。 When there is no imposed size, the jpanel takes the size of the inner component.当没有强加大小时,jpanel 采用内部组件的大小。

Note: GridBaLayout was used in my case注意:在我的案例中使用了 GridBaLayout

I would try:我会尝试:

panel.revalidate();
panel.repaint();

This will not necessarily set the panel to its preferred size, that is more dependent on what the layout manager decides to use.这不一定会将面板设置为其首选大小,这更取决于布局管理器决定使用的大小。

This is useful in cases where you have added/removed components from a panel that is currently displayed and visible.这在您从当前显示和可见的面板添加/删除组件的情况下很有用。

Update: Based on your screenshot I can say the following: 1) Consider programatically changing the divider location.更新:根据您的屏幕截图,我可以说以下内容:1) 考虑以编程方式更改分隔线位置。 2) Consider programatically resizing the window itself horizontally since it seems to be a little tight to show both sides of the split pane. 2) 考虑以编程方式水平调整窗口本身的大小,因为显示拆分窗格的两侧似乎有点紧张。 Or both.或两者。 You can set the divider location by doing您可以通过执行以下操作来设置分隔线位置

splitPane.setDividerLocation(newSize);

Keep in mind that there are two overloaded methods for this, one taking a float one taking an int.请记住,为此有两种重载方法,一种采用 float 一种采用 int。 The float does a percentage of the size while the int is the size in pixels.浮点数是大小的百分比,而 int 是以像素为单位的大小。 The size is for the left hand panel (or top panel for that orientation).尺寸适用于左侧面板(或该方向的顶部面板)。 I would consider possibly changing the divider location based on the preferred width of the panels.我会考虑根据面板的首选宽度更改分隔线的位置。

The javax.swing mysteries reveal themselves only gradually, and only to those who are prepared to offer many libations (particularly torn out clumps of hair, hours burning the midnight oil, etc.) to the gods of Swing. javax.swing 的奥秘只会逐渐显露出来,而且只会向那些准备为 Swing 之神献上许多祭品(尤其是扯下的头发、熬夜等)的人揭晓。

However, for this case in point I would suggest the following as a sort of Swiss army knife which usually does what you think the framework should do anyway:但是,对于这种情况,我建议将以下内容作为一种瑞士军刀,它通常会做您认为框架应该做的事情:

myJPanel.getTopLevelAncestor().validate()

As the sacred text says, "Validates this container and all of its subcomponents."正如神圣的文本所说,“验证此容器及其所有子组件。” (Container.validate). (Container.validate)。 NB getTopLevelAncestor() is a JComponent method.注意 getTopLevelAncestor() 是一个 JComponent 方法。

Can't remember how JSplitPane fits into this: try it and you'll probably find that it validates both components (right and left, top and bottom), but I would be surprised if changing the divider doesn't do this for you anyway.不记得 JSplitPane 是如何适应这个的:试试看,你可能会发现它验证了两个组件(右和左,顶部和底部),但如果改变分隔符对你不起作用,我会感到惊讶.

Here's an example of a panel which:这是一个面板示例,其中:

  • Resizes with it's parent.与它的父级一起调整大小。
  • Sets the width to the width of the parent.将宽度设置为父级的宽度。
  • Sets the height according to sum of the height of all of it's children.根据所有子项的高度总和设置高度。
JPanel panel = JPanel(new GridBagLayout())

panel.setMaximumSize(new Dimension(panel.getMaximumSize().width, panel.getPreferredSize().height))

panel.validate()
panel.repaint()

JSplitPanes are a bit fussy when it comes to its children's sizes, have a look at the Java tutorial . JSplitPanes 在涉及到它的孩子的大小时有点挑剔,看看Java 教程 Are you using the GridBagLayout correctly?您是否正确使用了 GridBagLayout? Looks like it's not setting the right JPanel's minimum size properly.看起来它没有正确设置正确的 JPanel 的最小尺寸。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM