你推荐使用哪些Swing布局?

44

Java库中有8个布局管理器,还有一堆第三方产品。

前几天,我尝试使用SpringLayout,但它对我来说行不通。请参阅我的其他问题。那么,如果你要设计一个Swing应用程序,并且想要精确地布局,你会选择哪种布局管理器?有什么有趣/有用的经验分享吗?

更新:是的,我知道不同的布局管理器适合不同的布局。但我预计大多数人在大部分情况下只使用1、2或者3种布局管理器,或者他们信奉一种万能的布局管理器,从不需要其他的布局管理器。通过足够多的回答,我预计看到类似于钟形曲线的分布,例如GridBagLayout或MigLayout峰值最高,而BoxLayout或FlowLayout则有少数使用者。

希望回答的分布将揭示出人们用于完成任务的首选布局管理器。


更新和总结

好吧,在近两天的时间里,MiGLayout明显领先!它的粉丝会很高兴听到这个消息——看起来这种布局管理器很快就会进入“官方”库中。

GroupLayout、FormsLayout和TableLayout相对较新,没有得到太多关注。也许其他人会像我一样惊讶地发现它们。

14个回答

67

MiGLayout 毫无疑问。老实说,这是我知道的唯一有意义的 Swing 布局管理器。

核心 JDK 中存在8个布局管理器的事实是一个好迹象,表明 Swing 的创建者完全不知道他们在尝试做什么。这并不是为了抨击 Swing 其余部分 - 它是一个很好的 GUI 工具包,除了布局管理器。


7
拥有一个接口的八个实现并不意味着弱点!(尽管不能保证没有其他无关的弱点存在。) - Tom Hawtin - tackline
17
完全不同意。不同的布局管理器适用于不同的目的,它们可以组合使用以实现几乎任何功能。这样做没有任何问题。 - Michael Borgwardt
8
不同的机器指令有不同的用途,可以组合使用以实现几乎任何功能。虽然这没有问题,但我更愿意使用高级语言来以更少的工作量实现相同的效果。 - Joonas Pulakka
3
我同意Joonas的观点。这些布局看起来是基于经验积累而建立的。这并没有什么不好,但这意味着一些旧的布局可能比它们本应该更有用少些。 - Carl Smotricz
3
大约折腾了30分钟的默认布局后,我找到了这个问题并进行了一些谷歌搜索。这个推荐太棒了,我在不到3秒钟内选择了MiGLayout(与仍然无法理解任何默认布局的30分钟相比)。 - Chris Browne
显示剩余8条评论

23
所有这些,都是结合在一起使用的。这就是整个重点。每个布局管理器都满足不同的需求,通过嵌套具有不同布局管理器的面板,您可以实现几乎任何布局。
“在单个面板中完成所有操作”的布局管理器,例如GridBagLayoutGroupLayout(还有许多第三方布局管理器),它们确实有其用处,主要是当您需要将布局的不同部分中的组件对齐时,但对于大型布局来说,它们通常会导致一个巨大且难以处理的混乱。

18

这取决于你要创建哪种GUI。你可能只需要使用一两个简单的布局,或者需要使用更高级的布局。我的整体布局管理器使用可能会像这样,但是它会根据项目而有所不同:

  • 65%的GridBagLayout-无论您需要做什么,都可以完成。
  • 15%的Box / BoxLayout-非常适合快速轻松地将几个组件粘在一起。
  • 12%的BorderLayout-很好地将按钮面板或信息面板附加到内容面板上。我几乎总是使用它向JFrame添加内容。
  • 3%FlowLayout-用于按钮面板很有用,但其他方面不太实用。
  • 3%CardLayout-主要在显示不同操作模式的不同内容面板的程序中很有用。
  • 2%其他布局-我很少需要其他任何布局,但偶尔其他布局很有用。

一旦您掌握了GridBagLayout的使用方法,最初编写起来并不那么困难,但是它的可读性和以后调试起来仍然不太理想。我最近尝试使用MiGLayout进行了某些工作,但失望的是,在特定情况下,MiGLayout实际上比GridBagLayout更复杂。

有些人像避开瘟疫一样避免GridBagLayout;但事实是,有些事情简单布局的任何组合都无法处理。将GUI拆分为不同的逻辑部分的面板是可以接受的,但我认为,如果您仅出于定位组件的目的创建了许多不必要的额外嵌套面板,则显然需要学习如何使用GridBagLayout(或其他类似高级布局,例如MiGLayout)。您可能会用令人不快的嵌套BorderLayout和GridLayout和BoxLayout使GUI看起来还好,但只要有人开始调整应用程序窗口和对话框的大小,使其比您最初设计的要小或大,您的GUI可能会看起来很糟糕,您的客户可能会因此对您的产品产生负面印象,因为您无法做好这么简单的事情。

更新:我已经使用Eclipse中的WindowBuilder工具一段时间了,它大大简化了许多布局的工作,特别是GridBagLayout。以前我花费很多时间手写布局,但是使用WindowBuilder或者其他类似的高级可视化编辑器,你可以在更短的时间内创建布局。


+1,非常感谢您详细周到的回答!我同意关于GBL的看法,但最近已经开始喜欢GroupLayout了,它能做一些GBL无法完成的事情。推荐使用!和您一样,我发现MiGLayout几乎很棒。 - Carl Smotricz
Box/BoxLayout 是什么意思? - turbanoff
@turbanoff,您可以将容器的布局设置为BoxLayout,这样它就可以表现得类似于FlowLayout的默认行为。或者,您可以直接创建一个垂直或水平的Box作为您的容器(而不是像将JPanel的布局设置为BoxLayout那样)。 - rob

15

DesignGridLayout既外观出众又通过流畅接口易于使用。

只需看例子:

enter image description here

只需几行简洁的代码:

    layout.row().grid(label("Last Name"))   .add(lastNameField) .grid(label("First Name"))  .add(firstNameField);
    layout.row().grid(label("Phone"))       .add(phoneField)    .grid(label("Email"))       .add(emailField);
    layout.row().grid(label("Address 1"))   .add(address1Field);
    layout.row().grid(label("Address 2"))   .add(address2Field);
    layout.row().grid(label("City"), 1)     .add(cityField);
    layout.row().grid(label("State"))       .add(stateField)    .grid(label("Postal Code")) .add(postalField);
    layout.row().grid(label("Country"), 1)  .add(countryField);
    layout.emptyRow();
    layout.row().center().add(newButton).add(deleteButton).add(editButton).add(saveButton).add(cancelButton);

感谢您指向这个有趣的布局管理器!我已经将它加入了书签。 - Carl Smotricz
很酷,但有个 bug,我的面板在每次调整窗口大小后会变得更大。 - Hiep
你好。你知道我能否使用DesignGridLayout并设置它不占用整个面板吗?或者在LastName文本框和FirstName标签之间添加一个“空格”? - nmartins

12

这取决于你需要哪种布局,这就是为什么有八种:

  1. BorderLayout,简单而且很有用,适用于设计常规内容框架(将主要内容放在中间,辅助内容则在两侧)。
  2. GridLayout,在您需要一个网格对象且每个对象大小相同时非常有用(如按钮?文本框?)。
  3. GridBagLayout,非常灵活,需要进行一些微调才能达到理想效果,并且比较冗长(但如果您希望做好这个工作,我推荐使用它)。
  4. FlowLayout,没啥用...不太像布局:只是将项目一个接一个地放置。
  5. CardLayout,非常适合选项卡或必须切换的子视图。
  6. BoxLayout,从未过多使用过。据说它应该是增强版的 FlowLayout,但它不够灵活,无法频繁使用。

1
BorderLayout 的关键在于默认情况下中心部分是“贪婪”的,并自动扩展其中的小部件以占用所有可用空间。所有其他插槽都不是“贪婪”的。 - kevinarpe

10

GroupLayout 是相当不错的。它最初是为 GUI Builder 应用程序使用而设计的,但我发现手工编码也非常简单明了。


2
我发现“相当不错”是一种轻描淡写!它非常通用,可以做一些GridBagLayout做不到的事情。推荐! - Carl Smotricz
2
我完全同意这种观点。我发现GroupLayout非常灵活。它可以产生一些很好的布局,而且可以很好地缩放。在用户可以通过拖动窗口角落进行调整大小的窗口中,这会产生美丽的结果。我也完全手工编写代码实现这个功能。 - Erick Robertson

8

FormLayoutJGoodies Forms包的一部分,对我来说非常有用。它并不完全灵活,因为它会努力让您的设计看起来很好。我在数十个项目中使用了几年,并且可以快速地生成漂亮的输出。

您可以使用人类可读的文本指定布局,然后添加组件。完成。


只有几次讨论: http://stackoverflow.com/questions/tagged/form-layout未被识别为错误的漏洞: https://java.net/jira/browse/FORMS-18 - Wolfgang Fahl

7

我通常使用边框布局网格布局进行设计,首先我会在纸上原型上设计用户界面,如下图:

alt text
(来源:usernomics.com)

之后我们可以将屏幕分为在边框布局中的网格布局。在这张图片中,我们看到了NORTH、CENTER、SOUTH三个部分(边框布局元素),每个部分的布局都可以是网格布局或边框布局,这取决于你自己。相同的布局也可以嵌套在其他布局中。


1
边框问题。如何让您的用户界面更加炫酷的顶级技巧。 - willcodejavaforfood

6

GridBagLayout。它几乎可以满足你所有的需求(有点),而且它在Java库中。不过,需要承认的是,它确实需要一些帮助,而且API很糟糕。

GroupLayout会让你的布局代码变得非常混乱。好吧,大多数人的GUI代码都是一团糟。但是你的代码不必如此!也许可以为这个布局管理器添加一个漂亮的界面,但我怀疑它可能需要克隆和拥有。

我不赞成引入外部依赖,除非它们真的必要。此外,许多第三方布局管理器使用数据字符串,这些字符串具有所有通常的问题。


是啊...似乎我是团队中唯一理解GridBagLayout的人。尽管如此,它仍然很痛苦。当我能够平均每个组件只写4行代码时,我会感到高兴,但那只适用于无聊的布局。肯定有更好的方法! - Carl Smotricz
1
嘿嘿,精通GridBagLayout几乎能让你在任何地方瞬间获得尊重。 ;) - Bombe
1
Bombe:回到 JDK1.02 时代,这几乎是你要做的第一件事。如今的孩子们! - Tom Hawtin - tackline
2
GridBagLayout可能需要很多代码,但这是因为它允许您进行许多其他布局不允许的自定义。人们说GridBagLayout很令人困惑,但我认为在嵌套面板中使用所有其他布局的奇怪大小和定位行为比学习GridBagLayout更令人困惑。 - Peter Dolberg
我编写了一个方便的包装类,它使用GridBagLayout和构建器模式类来创建GridBagConstraints - 这使得大多数组件成为一行代码,但同时也给了我自定义的能力! - xeruf

5

除了这个答案:取决于。它取决于您要创建哪种类型的框架(表单)。我不是Swing大师,但已经创建了一些(适度高级的)GUI,并且从未需要使用GridBagLayout管理器。我总是能够使用“更容易”的布局管理器组合来创建我的GUI。例如,您可以为您的框架提供BorderLayout,然后将另一个布局放置在该BorderLayout的SOUTH中。


我在刚开始学习Java编程时试图仅使用简单的布局来实现,但很快发现这样会导致在调整应用程序窗口大小时出现不良行为。 - rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接