复杂的布局管理
网格包布局
行列大小可改变,先建立表格,合并相邻单元格,组件指定在格内的对齐方式。
字体选择器组件:
- 另个指定字体和字体大小的组合框
- 两个组合框标签
- 两个选择粗体和斜体的复选框
- 一个显示示例字符串的文本区
将容器分解为单元格组成的网格,复选框跨两列,文本区跨4行。
gridx,gridy,gridwidth,gridheight参数
gridx,gridy指定了所添加组件左上角的行,列位置。坐标从0开始,都为0指示最左上角。
gridwidth,gridheight确定组件占据的行数和列数。
gridx,y(2,0)表示起始于0行2列(第3列),gridwidth,height(1,4)表示占据4行1列。
增量字段
weightx,y,设置为0,永远为初始大小,不会扩大或收缩。
fill和anchor参数
不希望组件拉伸至填满整个区域,需要设置fill约束,参数值:GridBagConstraints.NONE,HORIZONTAL,VERTICAL,BOTH.
组件没有填充整个区域,用anchor指定区域中的位置,有效值:
GridBagConstraints.CENTER,NORTH,NORTHEAST,EAST等.
填充
GridBagConstraints的Insets对象的left,top,right,bottom指定组件周围空间大小,外部填充。
网格包布局技巧
实际中不麻烦:
- 在纸上画出组件布局草图。
- 找出一个网格,小组件分别包含在一个单元格内,更大的组件跨越多个单元格。
- 用0,1,2,3...标识行与列,可以得出gridx,y,width,height的值。
- 思考每个组件是否填充所在单元格,不需要时如何对齐,也就是fill和anchor设置。
- 将所有增量设置为100,若想保持大小,设置为0.
- 编写代码,编译运行。
使用帮助类管理网格包布局
- 名字简短:GBC替换GridBagConstraints。
- 拓展以后,可以使用更短的名字如GBC.EAST
- 设置最常用,add(comp,new GBC(1,2));
- 两个构造器设置最常用参数:gridx和gridy,grdiwidth,gridheight,new GBC(1,2,1,4);
- x,y成对出现,便捷方法,newGBC(1,2).setWeight(100,100);
- 设置器返回this,可以链式调用,new GBC(1,2).setAnchor(GBC.EAST).setWeight(100,100);
- setInsets方法将构造Inserts对象,获取1像素inserts,可以调用:new GBC(1,2).setAnchor(GBC.EAST).setInsets(1)
示例代码
java
package swing;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
public class GridBagLayoutTest {
public static final int TEXT_ROWS = 10;
public static final int TEXT_COLUMNS = 20;
public static JComboBox<String> face;
public static JComboBox<Integer> size;
public static JCheckBox bold;
public static JCheckBox italic;
public static JTextArea sample;
public static void main(String[] args) {
JFrame frame = new JFrame("弹出菜单");
var layout = new GridBagLayout();
frame.setLayout(layout);
ActionListener listener = e -> updateSample();
//构造组件
var faceLabel = new JLabel("Face: ");
face=new JComboBox<String>(new String[] {"Serif","SansSerif","Monospaced","Dialog","DialogInput"});
face.addActionListener(listener);
//构造字体大小下拉选
var sizeLabel = new JLabel("Size: ");
size=new JComboBox<>(new Integer[] {24,8,10,12,15,18,36,48});
size.addActionListener(listener);
//是否加粗
bold=new JCheckBox("Bold");
bold.addActionListener(listener);
//是否斜体
italic = new JCheckBox("Italic");
italic.addActionListener(listener);
//文本区设置
sample=new JTextArea(TEXT_ROWS, TEXT_COLUMNS);
sample.setText("The quick brown fox jumps over the lazy dog!");
sample.setEditable(false);
sample.setLineWrap(true);
sample.setBorder(BorderFactory.createEtchedBorder());
//添加组件
frame.add(faceLabel,new GBC(0,0).setAnchor(GBC.EAST));
frame.add(face,new GBC(1,0).setFill(GBC.HORIZONTAL).setWeight(100, 0).setInsets(1));
frame.add(sizeLabel,new GBC(0,1).setAnchor(GBC.EAST));
frame.add(size,new GBC(1,1).setFill(GBC.HORIZONTAL).setWeight(100, 0).setInsets(1));
frame.add(bold,new GBC(0,2,2,1).setAnchor(GBC.CENTER).setWeight(100, 100));
frame.add(italic,new GBC(0,3,2,1).setAnchor(GBC.CENTER).setWeight(100, 100));
frame.add(sample,new GBC(2,0,1,4).setFill(GBC.BOTH).setWeight(100, 100));
updateSample();
frame.setSize(400, 400);
//初始打开为屏幕中央
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
int screenWidth = (int) screenSize.getWidth();
int screenHeight = (int) screenSize.getHeight();
//计算窗口位置
int x = (screenWidth - frame.getWidth())/2;
int y = (screenHeight - frame.getHeight())/2;
frame.setLocation(x, y);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public static void updateSample() {
var fontFace = (String)face.getSelectedItem();
int fontStyle = (bold.isSelected()?Font.BOLD:0)+(italic.isSelected()?Font.ITALIC:0);
int fontSize = size.getItemAt(size.getSelectedIndex());
var font = new Font(fontFace, fontStyle, fontSize);
sample.setFont(font);
sample.repaint();
}
}
java
package swing;
import java.awt.GridBagConstraints;
import java.awt.Insets;
public class GBC extends GridBagConstraints {
//左上角坐标
public GBC(int gridx,int gridy) {
this.gridx = gridx;
this.gridy = gridy;
}
//左上角坐标,所占行列
public GBC(int gridx, int gridy, int gridwidth, int gridheight) {
this.gridx = gridx;
this.gridy = gridy;
this.gridwidth=gridwidth;
this.gridheight=gridheight;
}
public GBC setAnchor(int anchor) {
this.anchor = anchor;
return this;
}
public GBC setFill(int fill) {
this.fill = fill;
return this;
}
public GBC setWeight(double weightx,double weighty) {
this.weightx = weightx;
this.weighty = weighty;
return this;
}
public GBC setInsets(int distance) {
this.insets = new Insets(distance, distance, distance, distance);
return this;
}
public GBC setInsets(int top,int left,int bottom,int right) {
this.insets = new Insets(top, left, bottom, right);
return this;
}
public GBC setIpad(int ipadx,int ipady) {
this.ipadx = ipadx;
this.ipady = ipady;
return this;
}
}