blog/source/_posts/miglayout-notes.md
2021-06-22 06:39:52 +08:00

277 lines
19 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: MigLayout的使用简记
tags:
- JVM
- Java
- GUI
- Swing
- MigLayout
categories:
- - JVM
- Java
keywords: 'java,swing,miglayout,gui'
mathjax: true
date: 2021-06-22 06:39:30
---
MigLayout是一款用于Swing和SWT、JavaFx的老牌布局管理器。虽然MigLayout已经出现了很长时间了但是它在进行UI布局的时候使用方法比较简单布局说明非常清晰代码量也不高是使用Java开发GUI应用时比较推荐的一个布局管理器。<!-- more -->MigLayout是一个采用表格方式布局排列的布局管理器也可以认为它采用的是Grid形式布局这个布局的特性与CSS 3中的Flex布局的特性相近。在设计MigLayout的布局的时候可以首先在设计稿上勾画横纵的表格明确各个组件占用空间的关系然后再根据MigLayout提供的布局约束描述命令对组件容器进行布局约束定义。
要在项目中使用MigLayout需要根据当前项目所使用的GUI技术来选择使用不同的包。
例如使用Maven进行项目构建可以选择以下依赖项。
```xml
<!--项目使用Swing-->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>11.0</version>
</dependency>
<!--项目使用JavaFx-->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-javafx</artifactId>
<version>11.0</version>
</dependency>
<!--项目使用SWT-->
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swt</artifactId>
<version>11.0</version>
</dependency>
```
对应的如果使用Gradle进行项目构建只需要将以上依赖定义中的GAV坐标提取出来即可。
## 布局参数
定义布局就必须使用尺寸和单位MigLayout设计了以下这些尺寸单位供布局定义使用。
- `""`空字符串作为单位时MigLayout将使用平台默认的单位和像素来计量。
- `px`,使用屏幕的像素计量,例如`10px`。
- `%`,使用相对于容器的百分比尺寸,例如`50%`表示在中间。
- `lp`,使用平台计算得到的逻辑像素,例如`10lp`。
- `pt`,点,一般为$\frac{1}{72} inch$,例如`10pt`。
- `mm`毫米这个单位会受到屏幕DPI的影响例如`10mm`。
- `cm`厘米这个单位会受到屏幕DPI的影响例如`10cm`。
- `in`英尺这个单位会收到屏幕DPI的影响例如`10in`。
- `sp`,相对屏幕尺寸的百分比,会根据屏幕的像素数进行计算。这个单位在使用的时候是书写在数字前面的,例如`sp 70`。
- `al`视觉边界对齐。取值0到1`0al`表示左对齐,`0.5al`表示居中,`1al`则表示右对齐。
- `null`,空值,表示值的缺失与不设定,可缩写为`n`。
在设定布局参数的时候除了可以使用数字与上面这些单位进行搭配以外还可以使用以下这些关键字来声明一些固定的尺寸这些尺寸将会由MigLayout自动完成计算。
- `related`,声明两个组件或者行列的尺寸是相关的,可以简写为`rel`或者`r`。
- `unrelated`,声明两个组件或者行列的尺寸是不相关的,可以简写为`unrel`或者`u`。
- `paragraph`,使用自动确定的段间距,可以简写为`para`或者`p`。
- `indented`,使用自动确定的缩进,可以简写为`ind`或者`i`。
- `minimum`,使用行列中出现的**最大**的最小尺寸值,可以简写为`min`。
- `preferred`,使用行列中出现的**最大**的期望尺寸值,可以简写为`pref`或者`p`。
- `maximum`,使用行列中出现的**最大**的最大尺寸值,可以简写为`max`。
## 布局管理器的创建
MigLayout有两种创建布局管理器实例的方法一种是使用无参构造函数一种是使用声明默认整体布局的有参构造函数。MigLayout的有参构造函数主要有以下几个。
- `MigLayout(LC)`,使用`LC`实例声明MigLayout的布局约束。
- `MigLayout(LC, AC)`,使用`LC`实例声明MigLayout的布局约束`AC`实例声明列布局约束。
- `MigLayout(LC, AC, AC)`,使用`LC`实例声明MigLayout的布局约束第一个`AC`实例声明列布局约束,第二个`AC`实例声明行布局约束。
- `MigLayout(String)`使用字符串描述MigLayout的布局约束。
- `MigLayout(String, String)`使用第一个字符串描述MigLayout的布局约束第二个字符串描述列布局约束。
- `MigLayout(String, String, String)`使用第一个字符串描述MigLayout的布局约束第二个字符串描述列布局约束第三个字符串描述行布局约束。
从以上列表可以看出MigLayout的构造函数实际上是分为三类的分别描述整体布局约束、列布局约束和行布局约束。不过虽然MigLayout支持使用`LC`和`AC`两个类来使用强类型约束的形式声明布局约束,但是在大部分情况下,还是推荐优先使用字符串来声明布局约束,因为字符串虽然类型约束很弱,但是描述性和可读性都很强,所需要书写的代码也比较少。
!!! note ""
其实`LC`和`AC`这两个类十分好记,`LC`是Layout Constraint布局约束的缩写`AC`是Axis Constraint轴向约束的缩写。在MigLayout中还有一个`CC`类它是Component Constraint组件约束的缩写。
### 整体布局约束
整体布局约束影响的是整个容器的布局如果使用无参构造函数实例化MigLayout将会直接使用在一行内顺序排布的布局方式而容器中组件的布局也完全由组件自己声明的布局来决定。整体布局中可以使用以下文字描述来对布局约束进行定义。
在所有的字符串描述中,多个布局约束描述命令之间使用`,`隔开,例如`wrap 3,fillx`。而使用`LC`类的时候,则只需要选择最终能够返回`LC`实例的方法即可,例如`new LC().wrapAfter(3).fillX()`。
!!! note ""
不仅整体布局约束中的约束描述命令是使用`,`隔开的,轴向布局约束和组件布局约束中的约束描述命令都是使用`,`隔开的。书写时只选择需要的布局约束进行声明即可。
| 约束描述命令 | 设定布局功能 |
|---|---|
| `wrap n` | 设定自动换行策略,`n`表示在第几列之后进行换行。 |
| `wrap` | 相当于`wrap 0`,会使容器内的组件按照轴向布局约束设置排列。 |
| `gap x y` | 设定单元格之间的间隙。 |
| `gapx x` | 设定单元格之间横向的间隙。 |
| `gapy y` | 设定单元格之间纵向的间隙。 |
| `nogrid` | 设定布局管理器不使用基于Grid的布局。 |
| `novisualpadding` | 设定不使用可见留白。 |
| `fill` | 组合`fillx`和`filly`的功能。 |
| `fillx` | 设定布局管理器总是尝试获取最大的横向空间。 |
| `filly` | 设定布局管理器总是尝试获取最大的纵向空间。 |
| `insets all` | 同时设定布局四周的留白空间,可以简写为`ins`。 |
| `insets top left bottom right` | 逐一设定布局四周的留白空间。 |
| `flowy` | 设置布局管理器沿纵向排列组件。 |
| `alignx x` | 设置组件在父组件中的横向对齐方式,可以缩写为`ax`。 |
| `aligny y` | 设置组件在父组件中的纵向对齐方式,可以缩写为`ay`。 |
| `align x y` | 组合设置`alignx`和`aligny`,可以缩写为`al`。 |
| `lefttoright` | 设定从左向右布局,可以缩写为`ltr`。 |
| `righttoleft` | 设定从右向左布局,可以缩写为`rtl`。 |
| `toptobottom` | 设定从上向下布局,可以缩写为`ttb`。 |
| `bottomtotop` | 设定从下向上布局,可以缩写为`btt`。 |
| `hidemode n` | 设置组件不可见时的处理方式。 |
| `nocache` | 如果组件的大小与容器的边界关联那么必须使用此项关闭Panel的缓存。 |
| `width BoundSize` | 同时设定布局的宽度,可以缩写为`w`参数使用BoundSize描述。 |
| `height BoundSize` | 同时设定布局的高度,可以缩写为`h`参数使用BoundSize描述。 |
| `wmax n` | 设定布局的最大宽度。 |
| `wmin n` | 设定布局的最小宽度。 |
| `hmax n` | 设定布局的最大高度。 |
| `hmin n` | 设定布局的最小高度。 |
#### 组件不可见的处理方式
命令`hidemode`可以接受以下这几个值作为参数。
| 可取值 | 布局处理方式 |
|:---:|---|
| `0` | 默认值,所有不可见的组件依旧会像它们可见时一样占据空间。 |
| `1` | 所有不可见的组件的尺寸将被设置为`0, 0`,但保留其所在单元格周围的间隙。 |
| `2` | 所有不可见的组件的尺寸将被设置为`0, 0`,并且其所在单元格周围的间隙也会被清零。 |
| `3` | 所有不可见的组件不会参与布局,并且不会占据单元格。 |
#### 对齐命令的参数
命令`align`、`alignx`和`aligny`三个命令所接受的参数值主要是以下这几个。
| 参数值 | 缩写 | 含义 |
|:---:|:---:|---|
| `top` | `t` | 顶部对齐 |
| `left` | `l` | 左对齐 |
| `bottom` | `b` | 底部对齐 |
| `right` | `r` | 右对齐 |
| `leading` | `lead` | 头部对齐 |
| `trailing` | `trail` | 尾部对齐 |
| `baseline` | `base` | 基线对齐 |
#### BoundSize描述
BoundSize是一组用来描述布局尺寸的参数组合其中由三个值组成最小尺寸、期望尺寸和最大尺寸。这是因为在布局尺寸在发生变化的时候我们通常都需要使用这三个值来对布局和组件的变化进行限定。所以在基本上所有需要使用具体尺寸值的位置都是使用BoundSize来声明的。BoundSize使用`最小值:期望值:最大值`的格式来声明,例如`30lp:50lp:80lp`。除了可以使用具体数值以外BoundSize还可以使用`null`、`rel`等需要MigLayout自行计算决定的关键字参数。
但是对于BoundSize来说经常会有以下常用的设置技巧存在这些也都是对于日常布局的需要而存在的。
- 仅设置单个值,例如`10`。这表示仅设置期望值,相当于`null:10:null`。
- 设置两个值,例如`10:20`。这表示设置最小值和期望值,相当于`10:20:null`。
- 使用`!`,例如`20!`。这表示最小值、期望值和最大值都使用相同的设置,相当于`20:20:20`。
如果需要BoundSize在声明Gap时让Gap能够尽可能的占据所有剩余的空间可以在BoundSize上附加`push`关键字,例如`gap 10!:push`或者`gap 5:10:20:push`。
### 轴向布局约束
轴向布局约束是用来定义容器内部每行单元格的的默认布局属性的。轴向布局约束采用`[]`来定义一行内每个单元格的布局属性,两个`[]`之间的表达式定义党员个之间的Gap的属性所以轴向布局约束的格式就是`[constraint,constraint]gap size[constraint,constraint]`。例如`[10!]10[10:20]`就定义了一行只有两个单元格的布局这个布局第一个单元格宽度为10第二个单元格的宽度是20两个单元格之间的间距是10。其中Gap Size可以使用所有BoundSize表达式来描述。
!!! note ""
如果不需要显式定义间距直接使用MigLayout的默认间距那么相邻的`][`就可以被`|`代替。例如`[10][10][10]`就可以简写为`[10|10|10]`。
轴向布局约束也有自己的一套约束描述命令,这些约束命令主要是使用在单元格的约束定义上。
| 约束描述命令 | 设定布局功能 |
|---|---|
| `sizegroup name` | 给指定的单元格设定尺寸组名称,拥有相同尺寸组名称的单元格将共享相同的尺寸设置。可以简写为`sg` |
| `fill` | 设定单元格中的组件的属性设置为`grow`,使组件将尽可能的占据所有可用横向空间,不会影响单元格空间。 |
| `nogrid` | 不使用单元格布局,而是使用流式布局代替。 |
| `grow n` | 设定尺寸增长的权重默认权重值是100已经设定的权重之间尺寸增长都按照权重的比例进行。 |
| `growprio n` | 设定尺寸的增长优先级,可以在尺寸发生变化时,优先使优先级高的行或者列达到最大尺寸。不影响单元格中的组件。 |
| `shrink n` | 与`grow`相反,设置尺寸缩小时的权重。 |
| `shrinkprio n` | 与`growprio`相反,设置尺寸缩小时的优先级。可以缩写为`shp`。 |
| `align a` | 设置组件在单元格内的对齐方式。可以缩写为`al`。 |
| `gap n` | 单独设置单元格前后的间隙大小。 |
| `gapbefore n` | 单独设置单元格前的间隙大小。 |
| `gapafter n` | 单独设置单元格后的间隙大小。 |
## 组件排布
MigLayout是一个行列布局管理器所以在默认情况下MigLayout总是沿着X轴按照组件的添加顺序逐一排列组件。例如以下示例。
```java
panel.setLayout(new MigLayout());
panel.add(new JLabel("Option 1"));
panel.add(new JTextField());
panel.add(new JLabel("Option 2"));
panel.add(new JTextField());
```
对于每个组件的布局属性是通过`.add()`方法的第二个参数“布局约束”来实现的,比如将组件换到另一行排列。所以上面这个示例可以像下面这样分成两行排列。
```java
panel.setLayout(new MigLayout());
panel.add(new JLabel("Option 1"));
panel.add(new JTextField(), "wrap"); // 布局将在这个组件之后换行
panel.add(new JLabel("Option 2"));
panel.add(new JTextField());
```
### 组件布局约束
组件布局约束也是通过一系列的约束描述命令来完成的虽然可以使用MigLayout提供的`CC`类来进行强类型形式的定义,但是为了更加简便的描述布局,字符串的形式还是更加简单明了一些。
| 约束描述命令 | 设定布局功能 |
|---|---|
| `wrap n` | 设定当前组件是本行最后一个组件,下一个组件将换行放置,`n`表示当前单元格之后需要保留的间隙大小。 |
| `newline n` | 设定在当前组件之前进行换行,当前组件将被放置在新的一行里。`n`表示上一行末尾需要保留的间隙大小。 |
| `push n` | 使组件的大小按照`n`定义的权重比例进行增长,可以单独使用`pushx`和`pushy`来定义横向和纵向。 |
| `skip n` | 跳过指定数量的单元格再放置当前组件。 |
| `span x y` | 在横向和纵向方向上合并指定数量的单元格。 |
| `spanx x` | 合并指定数量的横向单元格。 |
| `spany y` | 合并指定数量的纵向单元格。 |
| `split n` | 将当前单元格分割成指定数量的单元格,之后添加的组件将先被放置在分割出来的单元格里。 |
| `cell x y sx sy` | 设定组件将被放置到的单元格,其中`sx`和`sy`表示指定单元格的合并情况。 |
| `flowx`、`flowy` | 设定单元格中的组件排布方向。 |
| `width BoundSize` | 设定组件的宽,可以简写为`w`。 |
| `height BoundSize` | 设定组件的高,不影响单元格中的组件。可以简写为`h`。 |
| `wmin n`、`wmax n` | 设定组件的最小宽度和最大宽度。 |
| `hmin n`、`hmax n` | 设定组件的最小高度和最大高度。 |
| `grow x y` | 设定组件在指定方向上的尺寸增长权重。 |
| `growx x` | 设定组件在横向上的尺寸增长权重。 |
| `growy y` | 设定组件在纵向上的尺寸增长权重。 |
| `growprio n` | 设定组件尺寸的增长优先级。可以缩写为`gp`。 |
| `growpriox n` | 设定组件横向尺寸的增长的优先级。可以缩写为`gpx`。 |
| `growprioy n` | 设定组件纵向尺寸的增长的优先级。可以缩写为`gpy`。 |
| `shrink n` | 设定组件在尺寸缩小权重。 |
| `shrinkprio x y` | 设定组件尺寸缩小时的优先级。可以缩写为`shp`。 |
| `shrinkpriox n` | 设定组件横向尺寸缩小时的优先级。可以缩写为`shpx`。 |
| `shrinkprioy n` | 设定组件纵向尺寸缩写时的优先级。可以缩写为`shpy`。 |
| `sizegroup name` | 为组件设定一个尺寸组的名称拥有相同名称尺寸组的组件将具有相同的BoundSize。可以简写为`sg`。 |
| `sizegroupx name` | 为组件设定一个只保存横向尺寸的尺寸组名称。可以简写为`sgx`。 |
| `sizegroupy name` | 为组件设定一个只保存纵向尺寸的尺寸组名称。可以简写为`sgy`。 |
| `endgroup name` | 为组件设定一个终止组名称,拥有相同终止组名称的组件,将会使其右侧和底边保持对齐。可以简写为`eg`。 |
| `endgroupx name` | 为组件设定一个横向的终止组名称。可以简写为`egx`。 |
| `endgroupy name` | 为组件设定一个纵向的终止组名称,可以简写为`egy`。 |
| `gap l r t b` | 为组件设定其所在单元格的外周间隙。只设定一个值时表示四周都使用相同的BoundSize。另外可以使用`gapleft`、`gaptop`、`gapbottom`、`gapright`、`gapbefore`和`gapafter`来设定具体方向上的间隙大小。 |
| `gapx l r` | 为组件所在的单元格设置横向的外周间隙。只设定一个值时表示左右两侧都使用相同的BoundSize。 |
| `gapy t b` | 与`gapx`类似,但设置纵向间隙。 |
| `id [grp.] id` | 为组件设置一个ID这个ID可以用于不同组件之间的相互访问。 |
| `pos x y` | 将组件在容器中使用绝对定位放置。采用绝对定位的组件将不会被放入单元格内。 |
| `pos x y x2 y2` | 将组件在容器中采用绝对定位放置,并且使用`x2`、`y2`设定组件的大小边界。 |
| `x n`、`x2 n`、`y n`、`y2 n` | 设定组件的绝对定位边界。 |
| `dock s` | 将组件泊放在容器的边界上这个定位能力与BorderLayout类似。在泊放方向不是`center`的时候,`dock`命令可以被省略。泊放方向可取值有`west`、`south`、`east`、`north`和`center`,并且后续的泊放命令将会使之前的泊放被截断,并占据更多的空间。 |
| `pad t l b r` | 在单元格内部,组件的四周设置留白,如果只设置一个值则代表四个方向使用相同的值。 |
| `align x y` | 设置组件在单元格内的对齐,如果只设置一个值则代表在横总两个方向上都使用相同的对齐设置。可以简写为`al`。 |
| `alignx al` | 设置组件在单元格内的横向对齐,可以简写为`ax`。 |
| `aligny al` | 设置组件在单元格内的纵向对齐,可以简写为`ay`。 |
| `external` | 设置禁止组件更改布局的尺寸布局的尺寸由GUI控制。利用`id`可以关联的获取组件尺寸。 |
| `hidemode n` | 设置组件被隐藏的时候,处理布局变化的方式,参数取值与整体布局约束相同。 |
| `tag n` | 为组件打一个标签。 |
#### 组件的标签
标签可以用于标记和解释组件的用途并且还可以用来定义组件的排序但是需要注意的是这个排序是由系统决定的。在MigLayout中可以使用的标签有一下这些。
- `ok`,表示组件是“确认”按钮。
- `cancel`,表示组件是“取消”按钮。
- `help`,表示组件是“帮助”按钮,这个按钮通常会被放置在右侧。
- `help2`,表示组件是“帮助”按钮,这个按钮通常会被放置在左侧。
- `yes`,表示组件是“是”按钮。
- `no`,表示组件是“否”按钮。
- `apply`,表示组件是“应用”按钮。
- `next`,表示组件是“下一个”按钮。
- `back`,表示组件是“后退”按钮。
- `finish`,表示组件是“结束”按钮。
- `left`,表示按钮组件应该被始终放置在最左边。
- `right`,表示按钮组件应该始终被放置在最右边。