文章目录
一、Swing特点
- Swing与Awt
- Awt:
- 在java.awt包中
- 使用系统API编写,重量级框架
- 不同平台风格不统一
- Swing:
- 在javax.swing包中
- 使用纯Java语言编写,轻量级框架
- 风格统一,不依赖平台
- 可插入外观组件
- Awt:
二、Swing概述
-
窗体组件类结构:
java.lang.Object
java.awt.Component(图形对象)
java.awt.Container(容器对象)
javax.swing.JComponent(组件)
JPanel(面板)
JButton(按钮)
JLabel(标签)
JTextField(文本框)
JList(列表框)
……
java.awt.Window(窗口)
java.awt.Frame(窗体)
javax.swing.JFrame(窗体)
java.awt.Dialog(对话框)
javax.swing.JDialog(对话框)
三、常用的Swing组件概述
- 容器组件:
- JFrame 窗体
- JDialog 对话框
- JPanel 面板
- 功能组件:
- JButton 按钮
- JLabel 标签
- JCheckBox 多选按钮
- JRadioButton 单选按钮
- JTextField 文本框
- JPassword 密码框
- JComboBox 下拉框
- JTextArea 文本域
- JList 列表框
- JOptionPane 小对话框
四、JFrame窗体
public static void main(String[] args){
JFrame f = new JFrame("窗体标题");//创建窗体对象
f.setVisible(true);//设置窗体可见
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//隐藏窗口并终止程序
/*
窗体关闭时的参数:
EXIT_ON_CLOSE:隐藏窗口并终止程序
DO_NOTHING_ON_CLOSE:无任何操作
HIDE_ON_CLOSE:隐藏窗体但不终止程序
DISPOSE_ON_CLOSE:释放窗体资源(终止程序)
*/
f.setSize(300,200);//设置窗体的大小,单位:像素
f.setLocation(200,200);//设置窗体的坐标,单位:像素
f.setBounds(200,200,300,200);//代替前面两个方法,可同时设定窗体的大小和坐标,单位:像素
Container c = f.getContentPane();//获取窗体容器
c.setBackground(Color.WHITE);//设置窗体背景颜色
JLabel l = new JLabel("这是一个窗体");
c.add(l);//添加组件
c.remove(l);//删除组件
c.validate();//做完增删操作后要验证容器中的组件(刷新窗体)
//f.setContentPane(c);//重新载入容器(二者取其一即可)
f.setResizable(false);//设置窗体是否可以改变大小,true为可改变(默认),false为不可改变
}
注意: 在正式开发中通常使用继承JFrame的方式实现一个新窗口:
public class MainPage extends JFrame {
public MainPage(){
setTitle("MainPage");//设置窗体的标题
setVisible(true);//设置窗体可见
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//隐藏窗口并终止程序
setSize(300,200);//设置窗体的大小,单位:像素
setLocation(200,200);//设置窗体的坐标,单位:像素
setBounds(200,200,300,200);//代替前面两个方法,可同时设定窗体的大小和坐标,单位:像素
}
}
五、JDialog窗体
public class MyDialog extends JDialog {
public MyDialog(JFrame frame){
super(frame,"对话框标题",true);//在JFrame中生成一个对话框,通过super调用父类的构造方法
/*
第一个参数:父窗体对象
第二个参数:对话框标题
第三个参数:是否阻塞父窗体
*/
Container c = getContentPane();//获取窗体容器
c.add(new JLabel("这是一个对话框"));//向窗体容器中添加组件
setVisible(true);//设置窗体可见
setBounds(100,100,100,100);//设置窗体坐标的和大小
}
public static void main(String[] args){
JFrame f = new JFrame("父窗体");
f.setBounds(50,50,300,300);
Container c = getContentPane();
JButton btn = new JButton("弹出对话框");
c.add(btn);
f.setVisible(true);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
btn.addActionListener(new ActionListener(){//为按钮组件添加监听器
@Override
public void actionPerformed(ActionEvent e){
MyDialog dialog = new MyDialog(f);
dialog.setVisible(true);//设置对话框的可见性
}
});
}
}
六、标签的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,100,100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
setVisible(true);
JLabel l = new JLabel("这是一个标签");
l.setText("更改标签内容");//设置标签内容
System.out.println(l.getText());//获取标签内容
l.setFont(new Font("宋体",Font.BOLD,15));//设置标签字体,参数:字体名,字体粗细,字体大小
l.setForeground(Color.RED);//更改前景色(字体颜色)
c.add(l);
}
public static void main(String[] args){
new Demo();
}
}
七、图标的使用
public class Demo extends JFrame {
public Demo(){
setBounds(x,y,width,height);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
JLabel l = new JLabel("这是一个展示图片的标签");
/*通过URL获取图标路径*/
//URL url = Demo.class.getResource("iconName.png");//获取图片URL路径
//System.out.println(url);//测试URL路径是否正确
//Icon icon = new ImageIcon(url);//获取相应路径下的图片文件
/*或者直接写图标的绝对路径*/
Icon icon = new ImageIcon("src/iconName.png");
l.setIcon(icon);//通过JLabel添加图标
l.setSize(20,20);//注意:即使设置标签大小也无法设置图标大小
setVisible(true);
}
public static void main(String[] args){
new Demo();
}
}
八、控件布局
-
绝对布局(null布局)
-
使用绝对布局的窗口通常都是固定大小的,组件的位置和形状不会随着窗体的改变而变化
public class Demo extends JFrame { public Demo(){ setBounds(100,100,200,150); setDefaultCloseOperation(EXIT_ON_CLOSE); Container c = getContentPane(); c.setLayout(null);//将容器的布局设为绝对布局,需要和setResizable(false)搭配使用 /*注意:在绝对布局下容器中所有通过setBounds设置组件的位置是相对容器的位置,而不是相对窗口*/ setVisible(true); } }
-
-
流布局(FlowLayout)
-
从左到右排列,默认居中对齐;
-
流布局:像流水一样,向某个方向流动,遇到障碍就折回
public class Demo extends JFrame { public Demo(){ setBounds(100,100,300,200); setDefaultCloseOperation(EXIT_ON_CLOSE); Container c = getContentPane(); c.setLayout(new FlowLayout());//给容器设置流布局(默认居中对齐) //c.setLayout(new FlowLayout(FlowLayout.LEFT));//左对齐的流布局 //c.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));//加了水平间距和竖直间距的左对齐的流布局 for(int i = 0; i < 10; ++i){ c.add(new JButton("按钮" + i));//向容器中添加按钮 } setVisible(true); } public static void main(String[] args){ new Demo(); } }
-
-
边界布局(BorderLayout)
-
边界布局:东西南北中(EAST、WEST、SOUTH、NORTH、CENTER)
-
注意:添加组件时,需要指定区域,否则默认添加到CENTER区域;同一个区域的组件会相互覆盖
-
特性:纵向压缩只能看见南北,横向压缩东西南北中都能看见
public class Demo extends JFrame { public Demo(){ setBounds(100,100,350,200); setDefaultCloseOperation(EXIT_ON_CLOSE); Container c = getContentPane(); c.setLayout(new BorderLayout());//给容器设置边界布局 JButton b1 = new JButton("中"),b2 = new JButton("东"),b3 = new JButton("西"),b4 = new JButton("南"),b5 = new JButton("北"); c.add(b1,BorderLyout.CENTER); c.add(b2,BorderLyout.EAST); c.add(b3,BorderLyout.WEST); c.add(b4,BorderLyout.SOUTH); c.add(b5,BorderLyout.NORTH); setVisible(true); } }
-
-
网格布局(GridLayout)
-
网格布局:可指定行和列的布局样式
-
网格布局与流布局很相似,但网格布局几行几列是明确的,只会放缩组件的大小
-
若组件数量超过行列总数时,则自动重新划分行列,并不会覆盖
public class Demo extends JFrame { public Demo(){ setBounds(100,100,300,300); setDefaultCloseOperation(EXIT_ON_CLOSE); Container c = getContentPane(); c.setLayout(new GridLayout(7,3,5,5));//给容器设置网格布局,参数:行,列,水平间距,垂直间距 for(int i = 0; i < 20; ++i){ c.add(new JButton("按钮" + i)); } setVisible(true); } }
-
-
网格组布局(GridBagLayout)
-
使用方法:
- 先创建网格组布局对象:
GridBagLayout gbl = new GridBagLayout();
- 将容器的布局样式设置为网格组布局对象:
container.setLayout(gbl);
- 创建组件的约束对象:
GridBagConstraints gbc = new GridBagConstraints();
- 向容器中添加组件:
container.add(new JLabel("label"), gbc);
参数:组件对象,约束对象
- 先创建网格组布局对象:
-
GridBagConstraints 常用属性:
属性名 描述 gridx, gridy 组件所在的位置 gridwidth, gridheight 组件所占用的行数和列数 anchor 组件所在的方位(九个方位) fill 组件的填充方式(NONE,HORIZONTAL,VERTICAL,BOTH) insets 组件与单元格边距的最小距离(四个参数:top,left,bottom,right) ipadx, ipady 组件最开始的大小 weightx, weighty 一个单元格空间充足时的最大宽高 -
代码示例:
public class Demo { JFrame f = new JFrame();//主窗体 Container container;//主容器 void createFrame(){ container = f.getContentPane(); c.setLayout(new GridBagLayout());//为主容器设置网格组布局 f.setSize(800,600); f.setLocationRelativeTo(null);//自动居中,但需要先设置size f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } void init(){ GridBagConstraints g1 = new GridBagConstraints(); g1.gridx = 0; g1.gridy = 0; c.add(new JButton("组件1"), g1); GridBagConstraints g2 = new GridBagConstraints(); g2.gridx = 1; g2.gridy = 1; c.add(new JButton("组件2"), g2); GridBagConstraints g3 = new GridBagConstraints(); g3.gridx = 3; g3.gridy = 3; c.add(new JButton("组件3"), g3); } public static void main(String[] args){ Demo d = new Demo(); d.createFrame(); d.init();//init方法将组件添加进容器 d.f.setVisible(true); } }
-
九、下拉列表框的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,300,300);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(null);//使用绝对布局
//JComboBox<String> comboBox = new JComboBox<>();//通常使用的是String的泛型
//comboBox.addItem("身份证");//方法一:通过addItem添加选项
//comboBox.addItem("工作证");
//comboBox.addItem("学生证");
//String[] items = {"身份证","工作证","学生证"};//方法二:通过字符数组作参数添加选项
//JComboBox<String> comboBox = new JComboBox<>(items);
JComboBox<String> comboBox = new JComboBox<>();//方法三:通过下拉列表框模型添加选项
String[] items = {"身份证","工作证","学生证"};
ComboBoxModel cm = new DefaultComboBoxModel<>(items);//创建下拉列表模型,将字符数组作为参数
comboBox.setModel(cm);//将模型置入下拉列表中
JButton btn = new JButton("打印");//用于获取下拉列表中的数据
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
System.out.println("选中的索引:" + comboBox.getSelectedIndex());//获取选中索引
System.out.println("选中的值:" + comboBox.getSelectedItem());//获取选中的值
}
});
btn.setBounds(100, 10, 60, 20);
c.add(btn);
comboBox.setEditable(true);//将下拉列表设为可编辑(编辑后的值索引为-1)
comboBox.setBounds(10,10,80,21);
setVisible(true);
}
}
十、列表框的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,200,150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container container = getContentPane();
container.setLayout(null);
String[] items = {"元素1","元素2","元素3","元素4"};
//JList<String> list = new JList<>(items);//方法一:通过字符数组添加列表项
DefaultListModel<String> model = new DefaultListModelM<>();//方法二:通过默认列表模板添加列表项
for(String tmp : items){
model.addElement(tmp);//向模型中添加元素
}
JList<String> jl = new JList<>();
jl.setModel(model);//向列表中置入模型
jl.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//设置列表的选择模式
/*
SINGLE_SELECTION:单选
SINGLE_INTERVAL_SELECTION:只能连续选择相邻元素(要加ctrl)
MULTIPLE_INTERVAL_SELECTION:无限制,任意选
*/
JScrollPane js = new JScrollPane(jl);//为列表添加滚动条以展示显示不全的元素
js.setBounds(10,10,50,50);//为滚动容器设置大小
container.add(js);
JButton btn = new JButton("确认");
btn.setBounds(120,90,70,25);
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0){
List<String> values = jl.getSelectedValuesList();//获取列表中选中项的信息(注意是java.util.List)
for(String tmp : values){
System.out.println(tmp);
}
System.out.println("--- THE END ---");
}
});
setVisible(true);
}
public static void main(String[] args){
new Demo();
}
}
十一、文本框的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,200,150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextField jt = new JTextField();
jt.setColumns(20);//设置文本框长度,此处为20个字符
jt.setText("text");//设置文本
jt.setFont(new Font("黑体", Font.PLAIN, 20));//设置字体格式
c.add(jt);
JButton btn = new JButton("确认");
btn.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0){
System.out.println("文本框中的值为:" + jt.getText());//获取文本框中的文本值
jt.setText("");//清空文本框
jt.requestFocus();//获取焦点和光标
}
});
c.add(btn);
setVisible(true);
}
}
十二、密码框的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,200,150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JPasswordField jp = new JPasswordField();
jp.setColumns(20);//设置密码框长度,此处为20个字符
jp.setFont(new Font("黑体", Font.BOLD, 20));//设置字体格式
jp.setEchoChar("*");//设置回显字符
jp.addActionListener(new ActionListener(){//添加动作监听:回车
@Override
public void actionPerformed(ActionEvent arg0){
char[] ch = jp.getPassword();//获取密码的字符数组
String str = new String(ch);
System.out.println(str);
}
});
c.add(jp);
setVisible(true);
}
}
十三、文本域的使用
public class Demo extends JFrame {
public Demo(){
setBounds(100,100,200,150);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextArea jt = new JTextArea();
jt.setColumns(20);//设置文本框长度,此处为20个字符
jt.setText("Text");//设置文本
jt.setFont(new Font("黑体", Font.PLAIN, 20));//设置字体格式
jt.setRows(5);//设定文本域的行
jt.setColumns(20);//设定文本域的列
jt.append("添加内容");
jt.insert("插入", 2);//在第二个字符后面插入内容
JScrollPane js = new JScrollPane(jt);//添加滚动条
c.add(js);
setVisible(true);
}
}
十四、监听事件
- 监听事件简介
- 监听Listener:KeyListener, MouseListener, WindowListener, ActionListener
- 事件Event:KeyEvent, MouseEvent, WindowEvent, ActionEvent
- 动作事件监听器(ActionListener)
- 添加动作监听器ActionListener。添加方法:使用 组件.addActionListener()进行添加
- 将实例化的ActionListener添加进参数列表。实例化方法:重写方法actionPerformed(ActionEvent e), 也就是当组件发生操作时调用的方法
- 焦点事件监听器(FocusListener)
- 添加焦点监听器FocusListener。添加方法:使用 组件.addFocusListener()进行添加
- 将实例化的FocusListener添加进参数列表。实例化方法:重写方法focusGained(FocusEvent e)和focusLost(FocusEvent e), 也就是当组件获取焦点时调用的方法和失去焦点时调用的方法。