前言:Swing很容易写也很难控制的原因在于布局管理器,这个对象控制widget的大小与位置。本章主要学习Swing和布局管理器。
组件
组件(widget),也称为元件(Component),因为几乎所有组件继承自javax.swing.JComponent
组件可以嵌套,即组件上能安置其他组件,大部分情况是将按钮等交互组件放置在框架和面板等背景组件上。
布局管理器
布局管理器是与特定组件相关联的Java对象,大多数是背景组件。布局管理器用来控制所关联组件上携带的其他组件。如框架带有面板,面板带有按钮,则面板的布局管理器控制按钮的大小与位置,框架同理,按钮不需要布局管理器。
布局管理器具有不同类型,即自定义布局规则。
嵌套布局
JPanel panelA = new JPanel();
JPanel panelB = new JPanel();
panelB.add(new JButton("button1"));
panelA.add(panelB);
布局管理器的工作
不同布局管理器有不同的组件放置方法(如垂直堆放)
布局过程
1)制作面板并加上按钮
2)面板的布局管理器询问每个组件理想大小
3)面板的布局管理器以其布局策略决定是否应该尊重按钮的愿望
4)把面板加到框架上
5)框架的布局管理器询问面板的理想尺寸
6)框架的布局管理器根据其布局策略决定是否尊重面板的意愿
三类管理器
BorderLayout
该管理器将背景组件分割为5个区域。每个区域放置一个组件,组件通常不会取得默认的大小,是框架默认的布局管理器
FlowLayout
面板默认的布局管理器
该管理器行为类似于文书处理程序的版面配置方式,组件按理想的尺寸大小呈现,从左到右按照加入的顺序以可能换行的方式排列,即组件放不下时放到下一行。
BoxLayout
类似于FlowLayout让每个组件使用默认理想的尺寸大小,按照加入的顺序来排列,但此管理器以垂直方式排列,且不会自动换行,会让你插入某种类似换行的机制来强制组件从新的一行排列。
Borderlayout布局的五个区域:
东,西,北,南与中央区
import javax.swing.*;
import java.awt.*;
public class Button1{
public static void main(String[] args){
Button gui = new Button1();
gui.go();
}
public void go(){
JFrame frame = new JFrame();
JButton button = new JButton("click me");
frame.getContentPane().add(BorderLayout.EAST,button);
frame.setSize(200,200);
frame.setVisible(true);
}
}
让按钮要求更多的高度
用更大的字体让按钮更高
public void go(){
JFrame frame = new JFrame();
JButton button = new JButton("click me");
Font bigFont = new Font("serif",Font.BOLD,28);
button.setFont(bigFont);
frame.getContentPane().add(BorderLayout.NORTH,button);
frame.setSize(200,200);
frame.setVisible(true);
}
总结
若在东区或者西区,宽度由自己决定,但高度受布局管理器的控制,若在北区或者南区,情况则相反。对于中间区域,则只能看扣除周围组件剩余的空间。
南北先占位,东西的高度需要扣除南北高度,东西区会取得预设的宽度而南北会取得预设的高度。
FlowLayout布局
组件流向:依次从左到右,从上到下
import javax.swing.*;
import java.awt.*;
public class Panel1{
public static void main(String[] args){
Panel1 gui = new Panel1();//调试panel的类的对象
gui.go();
}
public void go(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setBackground(Color.darkGray);//便于观察
JButton button = new JButton("shock me");
panel.add(button); //若再添加字少的按钮,只会水平排列(先从左到右)
frame.getContentPane().add(BorderLayout.EAST,panel);
frame.setSize(200,200);
frame.setVisible(true);
}
}
BoxLayout布局
适合要求垂直排列的情形
public void go(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.setBackground(Color.darkGray);//便于观察
panel.setLayout(new BoxLayout(panell,BoxLayout.Y_AXIS));
//构造函数参数为组件类型和轴向选择
JButton button = new JButton("shock me");
panel.add(button); //若再添加字少的按钮,只会水平排列(先从左到右)
frame.getContentPane().add(BorderLayout.EAST,panel);
frame.setSize(200,200);
frame.setVisible(true);
}
1)JFrame不能直接加组件是因为JFrame是让事物显示在画面上的节点,swing的组件纯粹由Java构成,JFrame必须连接到底层的操作系统以便存取显示装置,把面板想作安置在JFrame上的100%纯Java层,而JFrame是支撑面板的框架,可以用自定义的JPanel换掉框架的面板
myFrame.setContentPane(myPanel);
2)GUI关系
框架-->ContentPanel-->Panel-->组件
可通过创建Panel并将其作为ContentPanel来替换掉框架的布局管理器
3)组件有setSize()方法,但布局管理器会忽略,理想大小是根据组件确实所需的大小计算(组件自行计算),布局管理器会调用组件的getPreferredSize()方法,但此方法不会考虑之前对setSize()的调用。
4)可调用setLayout(null)直接设定画面的位置和大小,而不通过布局管理器
5)可调用setLayout()改变面板的布局管理器