有几次,我因为建议使用以下方法而受到批评:

setPreferredSize setMinimumSize setMaximumSize

Swing组件。当我想要定义显示的组件之间的比例时,我没有看到任何替代它们的使用。有人告诉我:

对于布局,答案总是一样的:使用合适的 LayoutManager

我在网上搜索了一下,但我还没有找到任何关于这个主题的全面分析。我有以下几个问题:

Should I completely avoid the use of those methods? The methods have been defined for a reason. So when should I use them? In which context? For what purposes? What exactly are the negative consequences of using those methods? (I can only think adding portability between systems with different screen resolution). I don't think any LayoutManager can exactly satisfy all desired layout needs. Do I really need to implement a new LayoutManager for every little variation on my layout ? If the answer to 4 is "yes", won't this lead to a proliferation of LayoutManager classes which will become difficult to maintain? In a situation where I need to define proportions between children of a Component (eg, child1 should use 10% of space, child2 40% ,child3 50%), is it possible to achieve that without implementing a custom LayoutManager?


当前回答

我的看法与公认的答案不同。

1)我应该完全避免使用这些方法吗?

不要避免!它们的作用是向布局管理器表达组件的大小限制。如果你不使用任何布局管理器,你可以避免使用它们,并尝试自己管理可视化布局。

不幸的是,Swing没有提供合理的默认尺寸。但是,与其设置组件的尺寸,不如使用合理的默认值降低您自己的组件。(在这种情况下,在你的子类中调用setXXX。)或者,您可以重写getXXX方法以达到同样的效果。

2)定义方法是有原因的。那么什么时候使用它们呢?在什么情况下?为了什么目的?

Always. When you create a component, set its realistic min/preferred/max size according to the use of that component. For example, if you have a JTextField for entering country symbols such as UK, its preferred size shall be as wide to fit two chars (with the current font, etc.) but probably it is meaningless to let it grow any bigger. After all, country symbols are two chars. As opposite, if you have a JTextField for entering e.g. a customer name, it can have a preferred size for like the pixel size for 20 chars, but can grow to bigger if the layout is resized, so set the maximum size to more. At the same time, having a 0px wide JTextField is pointless, so set a realistic minimum size (I would say the pixel size of 2 chars).

3)使用这些方法的负面后果究竟是什么?

(我只能考虑在不同屏幕分辨率的系统之间增加可移植性)。

没有负面后果。这些是布局管理器的提示。

4)我认为任何LayoutManager都不能完全满足所有所需的布局需求。

我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

不,绝对不是。通常的方法是级联不同的基本布局管理器,如水平布局和垂直布局。

例如,下面的布局:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

有两部分。左右部分为水平布局。右边的部分是一个添加到水平布局的JPanel,这个JPanel有一个垂直布局,垂直布局按钮。

当然,在现实生活的布局中,这可能会变得棘手。因此,如果你要开发严肃的东西,基于网格的布局管理器(如MigLayout)会更好。

5)如果4的答案是“是”,这是否会导致LayoutManager类的激增,这将变得难以维护?

不,你绝对不应该开发布局管理器,除非你需要一些非常特别的东西。

6)在需要定义比例的情况下……

在一个组件的子组件之间(例如,child1应该使用10%的空间,child2应该使用40%的空间,child3应该使用50%的空间),是否可以在不实现自定义LayoutManager的情况下实现这一目标?

基本上,一旦设置了正确的首选大小,您可能不希望在百分比中执行任何操作。简单地说,因为百分比是没有意义的(例如,有一个JTextField的窗口大小的10%是没有意义的-因为一个可以缩小窗口,使JTextField成为0px宽,或可以展开窗口,使JTextField是跨两个显示在一个多显示设置)。

但是,有时你可能会使用百分比来控制gui中较大的构建块的大小(例如面板)。

您可以使用JSplitPane,在这里您可以预先设置两边的比例。或者,您可以使用MigLayout,它允许您以百分比、像素和其他单位设置此类约束。

其他回答

我的看法与公认的答案不同。

1)我应该完全避免使用这些方法吗?

不要避免!它们的作用是向布局管理器表达组件的大小限制。如果你不使用任何布局管理器,你可以避免使用它们,并尝试自己管理可视化布局。

不幸的是,Swing没有提供合理的默认尺寸。但是,与其设置组件的尺寸,不如使用合理的默认值降低您自己的组件。(在这种情况下,在你的子类中调用setXXX。)或者,您可以重写getXXX方法以达到同样的效果。

2)定义方法是有原因的。那么什么时候使用它们呢?在什么情况下?为了什么目的?

Always. When you create a component, set its realistic min/preferred/max size according to the use of that component. For example, if you have a JTextField for entering country symbols such as UK, its preferred size shall be as wide to fit two chars (with the current font, etc.) but probably it is meaningless to let it grow any bigger. After all, country symbols are two chars. As opposite, if you have a JTextField for entering e.g. a customer name, it can have a preferred size for like the pixel size for 20 chars, but can grow to bigger if the layout is resized, so set the maximum size to more. At the same time, having a 0px wide JTextField is pointless, so set a realistic minimum size (I would say the pixel size of 2 chars).

3)使用这些方法的负面后果究竟是什么?

(我只能考虑在不同屏幕分辨率的系统之间增加可移植性)。

没有负面后果。这些是布局管理器的提示。

4)我认为任何LayoutManager都不能完全满足所有所需的布局需求。

我真的需要为我的布局上的每个小变化实现一个新的LayoutManager吗?

不,绝对不是。通常的方法是级联不同的基本布局管理器,如水平布局和垂直布局。

例如,下面的布局:

<pre>
+--------------+--------+
| ###JTABLE### | [Add]  | 
| ...data...   |[Remove]|
| ...data...   |        |
| ...data...   |        |
+--------------+--------+
</pre>

有两部分。左右部分为水平布局。右边的部分是一个添加到水平布局的JPanel,这个JPanel有一个垂直布局,垂直布局按钮。

当然,在现实生活的布局中,这可能会变得棘手。因此,如果你要开发严肃的东西,基于网格的布局管理器(如MigLayout)会更好。

5)如果4的答案是“是”,这是否会导致LayoutManager类的激增,这将变得难以维护?

不,你绝对不应该开发布局管理器,除非你需要一些非常特别的东西。

6)在需要定义比例的情况下……

在一个组件的子组件之间(例如,child1应该使用10%的空间,child2应该使用40%的空间,child3应该使用50%的空间),是否可以在不实现自定义LayoutManager的情况下实现这一目标?

基本上,一旦设置了正确的首选大小,您可能不希望在百分比中执行任何操作。简单地说,因为百分比是没有意义的(例如,有一个JTextField的窗口大小的10%是没有意义的-因为一个可以缩小窗口,使JTextField成为0px宽,或可以展开窗口,使JTextField是跨两个显示在一个多显示设置)。

但是,有时你可能会使用百分比来控制gui中较大的构建块的大小(例如面板)。

您可以使用JSplitPane,在这里您可以预先设置两边的比例。或者,您可以使用MigLayout,它允许您以百分比、像素和其他单位设置此类约束。

大多数人对这些方法知之甚少。您绝对不应该忽略这些方法。这取决于布局管理器是否遵守这些方法。这个页面有一个表,显示了哪些布局管理器尊重哪些方法:

http://thebadprogrammer.com/swing-layout-manager-sizing/

我已经写了8年多的Swing代码,JDK中包含的布局管理器一直满足我的需求。我从来没有需要第三方布局管理器来实现我的布局。

我会说,你不应该尝试给布局管理器提示这些方法,直到你确定你需要他们。做你的布局,不给任何大小提示(即让布局管理器做它的工作),然后你可以做一些小的修改,如果你需要。

在这种情况下,我需要定义一个组件的孩子之间的比例(孩子1应该使用10%的空间,孩子2 40%,孩子3 50%),是否有可能在不实现自定义布局管理器的情况下实现?

也许GridBagLayout可以满足你的需求。除此之外,网络上有大量的布局管理器,我打赌有一个符合你的要求。

这里有很多很好的答案,但我想补充一点关于为什么你应该避免这些问题的原因(这个问题又出现在一个重复的主题中):

除了少数例外,如果你正在使用这些方法,你可能正在微调你的GUI,使其在特定的外观上看起来更好(以及与系统相关的设置,例如你首选的桌面字体等)。这些方法本身并不是邪恶的,但是使用它们的典型原因是邪恶的。一旦你开始调整布局中的像素位置和大小,你就会在其他平台上面临GUI崩溃(或者至少看起来很糟糕)的风险。

例如,尝试更改应用程序的默认外观。即使只是使用平台上可用的选项,您也可能会惊讶于结果呈现的糟糕程度。

因此,为了保持GUI在所有平台上的功能性和美观性(记住,Java的主要好处之一是它的跨平台性),您应该依靠布局管理器等来自动调整组件的大小,以便在特定的开发环境之外正确地呈现。

综上所述,您当然可以设想这些方法是合理的。同样,它们本身并不是邪恶的,但它们的使用通常是指示潜在GUI问题的一个大危险信号。只要确保你意识到如果/当你使用它们时可能会出现很高的并发症,并且总是尝试和思考是否有另一种外观和感觉独立的解决方案来解决你的问题——通常你会发现这些方法是不必要的。

顺便说一下,如果你发现自己对标准的布局管理器感到沮丧,有很多好的免费、开源的第三方布局器,例如JGoodies的FormLayout或MigLayout。一些GUI构建器甚至内置了对第三方布局管理器的支持——例如,Eclipse的WindowBuilder GUI编辑器附带了对FormLayout和MigLayout的支持。

如果你在Java Swing的布局上遇到了麻烦,那么我可以强烈推荐由Karsten Lentzsch免费提供的JGoodies FormLayout,它是Forms免费软件库的一部分。

这个非常流行的布局管理器非常灵活,可以开发非常精致的Java ui。

您将在这里找到Karsten的文档,以及eclipse的一些相当不错的文档。