2020.2.8
学习目的:掌握Swing组件的使用,能够做一些简单的小窗体或登录界面,如QQ的登录界面
下面将详细介绍Swing包下的几个常用组件类
JFrame窗体
import java.awt.*;
import javax.swing.*;
public class Demo {
public static void main(String[] args) {
JFrame f=new JFrame("这是一个窗体");
f.setVisible(true);//设置窗体可见
/*
* JFrame的几个关闭窗体的常量
* 1.EXIT_ON_CLOSE:隐藏窗体并停止程序
* 2.DO_NOTHING_ON_CLOSE:无任何关闭操作,窗体也无法隐藏
* 3.HIDE_ON_CLOSE:隐藏窗体,但不停止程序
* 4.DISPOSE_ON_CLOSE:释放窗体资源,只针对窗体,其他代码依旧执行
*/
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// f.setSize(300,200);//设置大小,单位:像素
// f.setLocation(500,500);//设置窗体位置,单位:像素
f.setBounds(500,500,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);//设置窗体是否可以改变大小
//f.getX()获取窗体的x坐标 f.getY()获取窗体的y坐标
}
}
上面创建窗体的方法过于麻烦,在真正开发时,会让Demo继承JFrame,然后在Demo类的构造方法中直接使用里面的方法即可,最后在main方法中创建Demo类的对象
JDialog窗体
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Demo extends JDialog {
public Demo(JFrame frame){
/*
* 第一个参数:父窗体对象
* 第二个参数:对话框标题
* 第三个参数:是否阻塞父窗体
*/
super(frame,"对话框标题",true);
Container c=getContentPane();//获取窗体容器
c.add(new JLabel("这是一个对话框"));
setBounds(500,200,500,500);//设置窗体坐标和大小
}
public static void main(String[] args) {
final JFrame f=new JFrame("父窗体");
f.setBounds(500,500,300,300);
Container c=f.getContentPane();
JButton btn=new JButton("弹出对话框");
c.setLayout(new FlowLayout());//设置布局,采用流布局
c.add(btn);
f.setVisible(true);
f.setDefaultCloseOperation(EXIT_ON_CLOSE);
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
Demo d=new Demo(f);
d.setVisible(true);//设置窗体可见
}//匿名内部类
});
}
}
注: 1.阻塞窗体的意思是不能点击和操作父窗体,使用super关键字调用父类的方法
2.ActionListener是一个接口,监听事件使用匿名内部类实现该接口,对动作方法进行重写,从而点击按钮就创建对话框窗体的对象,然后调用Demo类的构造方法来创建对话框窗体
标签的使用
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setVisible(true);
setBounds(300,200,200,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
JLabel l=new JLabel("这是一个标签");
c.add(l);
// l.setText("更改标签内容");
// System.out.println(l.getText());//获取标签内容
/*
* 第一个参数是使用哪种字体
* 第二个参数是字体的样式,属于Font类的静态属性
* 第三个参数是字体的大小
*/
l.setFont(new Font("宋体",Font.BOLD,50));
l.setForeground(Color.red);//更改字体颜色
}
public static void main(String[] args) {
new Demo();
}
}
标签的主要作用是展示一段文字
图片的使用
在java窗体中添加图片用的是标签JLabel里的setIcon方法
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class Demo extends JFrame{
public Demo(){
setBounds(200,300,500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
JLabel l=new JLabel("这是一个标签");
c.add(l);
URL url=Demo.class.getResource("java.png");
System.out.println(url);
Icon icon=new ImageIcon(url);
l.setIcon(icon);
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
icon是图片的对象,Icon是一个接口,使用它的一个实现类ImageIcon进行实例化,ImageIcon的参数是地址,即图片所在文件的路径,此处采用当前类.class.getResource获取当前类编译之后的文件的路径,而不是获取源文件即代码所在的路径,在eclipse中,编译之后产生的文件放在bin文件中,而Androidstudio中的java模板编译文件则放在build文件中,所以我们只需要将图片放在对应的编译文件夹中即可,此处是build文件夹
图片文件展示.png
或者将图片拖入Demo类同包下,然后将它的地址详细化,更直观,但不灵活
String path="D:\\java\\Java\\day1\\src\\main\\java\\swu\\cx\\day1\\java.png";
Icon icon=new ImageIcon(path);
布局
1.绝对布局
绝对布局是指将组建用横纵坐标将其固定,布局传入的参数为null坐标图.png
单位是像素,使用绝对布局的窗口通常都是固定大小的,组件的位置和形状不会随着窗体的改变而发生变化,即组件的大小和位置被写死了
绝对布局.png
下面是对应的代码
import java.awt.Container;
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setBounds(400,400,400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(null);//将容器的布局设为绝对布局
JButton b1=new JButton("按钮1");
JButton b2=new JButton("按钮2");
b1.setBounds(20,20,100,30);//设置按钮在容器中的坐标和大小
b2.setBounds(20,60,100,30);
c.add(b1);
c.add(b2);
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
2.流布局(FlowLayout)
从左向右排列,默认居中对齐,下图为默认的居中对齐,LEFT,RIGHT分别为居左和居右流布局.png
流布局像水流一样灵活,会随着窗体的大小改变而发生位置变化,没有固定的坐标
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setBounds(400,400,400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));//设置为左对齐,组件间的水平间距和垂直间距都为20
for(int i=0;i<10;i++) {
c.add(new JButton("按钮"+i));//循环添加10个按钮
}
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
3.边界布局(BorderLayout)
边界布局是把容器分为东西南北中5个区域,组件的位置和大小会随着窗体的变化而发生改变,添加组件时,需要指定区域,否则默认添加到CENTER区,同一区域的组件会相互覆盖
边界布局.png
东西区域不到顶
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setBounds(400,400,400,400);
setDefaultCloseOperation(JFrame.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,BorderLayout.CENTER);//中部添加按钮
c.add(b2,BorderLayout.EAST);//东部添加按钮
c.add(b3,BorderLayout.WEST);//西部添加按钮
c.add(b4,BorderLayout.SOUTH);//南部添加按钮
c.add(b5,BorderLayout.NORTH);//北部添加按钮
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
4.网格布局(GridLayout)
new GridLayout(行,列,水平间距,垂直间距)
网格布局.png
网格布局中的组件大小会随着窗体大小的改变而发生改变,若组件数量超过网格数量则会重新布局,自动添加网格的数量
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo(){
setBounds(400,400,400,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new GridLayout(5,3,5,5));
for(int i=0;i<15;i++){
c.add(new JButton("按钮"+i));
}
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
5.网格组布局(GridBagLayout)
图示为网格组布局的使用方法网格组布局使用步骤.png
GridBagConstraints常用属性
1.gridx,gridy 组件所在的位置
2.gridwidth,gridheight 组件占用的行数和列数
3.anchor 组件所在的方位
4.fill 组件的填充方式
5.insets 组件与单元格边缘的最小距离
6.ipadx,ipady 组件的首选大小
7.weightx,weighty 一个单元格的最大宽高
一.gridx,gridy,gridwidth,gridheight
import java.awt.*;
import javax.swing.*;
public class Demo {
JFrame f=new JFrame();
Container c;
void createFrame(){
c=f.getContentPane();
c.setLayout(new GridBagLayout());//获取容器后马上设置布局方式
f.setSize(800,600);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
void createJButton(){
for(int i=0;i<9;i++){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=i;
g1.gridy=0;
c.add(new JButton("组件"),g1);
GridBagConstraints g2=new GridBagConstraints();
g2.gridx=0;
g2.gridy=i;
c.add(new JButton("组件"),g2);
}
}//创建按钮矩阵
void init(){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=1;
g1.gridy=1;
g1.gridwidth=1;
g1.gridheight=1;
c.add(new JButton("组件"),g1);
GridBagConstraints g2=new GridBagConstraints();
g2.gridx=2;
g2.gridy=2;
g2.gridwidth=2;
g2.gridheight=1;
c.add(new JButton("组件"),g2);
GridBagConstraints g3=new GridBagConstraints();
g3.gridx=4;
g3.gridy=3;
g3.gridwidth=2;
g3.gridheight=2;
c.add(new JButton("组件"),g3);
}
public static void main(String[] args) {
Demo d=new Demo();
d.createFrame();
d.createJButton();
d.init();
d.f.setVisible(true);
}
}
二.fill属性填充方式
填充图解.png
若组件的大小小于给定的单元格大小,则会对应如图的几种填充方式
void init(){
GridBagConstraints g1=new GridBagConstraints()
g1.gridx=1;
g1.gridy=1;
g1.gridwidth=2;
g1.gridheight=2;
c.add(new JButton("none"),g1);
GridBagConstraints g2=new GridBagConstraints()
g2.gridx=3;
g2.gridy=1;
g2.gridwidth=2;
g2.gridheight=2;
g2.fill=GridBagConstraints.HORIZONTAL;
c.add(new JButton("HORIZONTAL"),g2);//水平填充
GridBagConstraints g3=new GridBagConstraints()
g3.gridx=5;
g3.gridy=1;
g3.gridwidth=2;
g3.gridheight=2;
g3.fill=GridBagConstraints.VERTICAL;
c.add(new JButton("VERTICAL"),g3);//垂直填充
GridBagConstraints g4=new GridBagConstraints()
g4.gridx=7;
g4.gridy=1;
g4.gridwidth=2;
g4.gridheight=2;
g4.fill=GridBagConstraints.BOTH;
c.add(new JButton("BOTH"),g4);//上下左右填充
}
三.anchor属性
anchor.png
上图为anchor属性的9个方位,下面以南为例
void init(){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=1;
g1.gridy=1;
g1.gridwidth=2;
g1.gridheight=2;
g1.anchor=GridBagConstraints.SOUTH;//放在正南边上
c.add(new JButton("组件"),g1);
g1.fill=GridBagConstraints.BOTH;
g1.anchor=GridBagConstraints.CENTER;
JPanel p=new JPanel();
p.setBackground(Color.blue);
c.add(p,g1);//添加面板,使方位效果更明显
}
四.insets属性
定义组件在单元格中的位置,它是一个类,所以是一种对象属性insets.png
void init(){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=1;
g1.gridy=1;
g1.insets=new Insets(10,10,10,10);
c.add(new JButton("组件"),g1);
}
网格组布局会采用每一行最高的那个组件,每一列最宽的那个,所以即使是一行也会拉开距离
五.ipadx,ipady属性
值为正,则放大,为负,则缩小
void init(){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=2;
g1.gridy=2;
g1.ipadx=10;
g1.ipady=10;
c.add(new JButton("组件"),g1);
GridBagConstraints g2=new GridBagConstraints();
g2.gridx=4;
g2.gridy=2;
g2.ipadx=-10;
g2.ipady=-10;
g2.insets=new Insets(10,10,10,10);
c.add(new JButton("组件"),g2);
}
weightx,weighty属性
如果对组件设置了weightx,weighty属性,并且空间充足,则组件会保持设置的大小
void init(){
GridBagConstraints g1=new GridBagConstraints();
g1.gridx=2;
g1.gridy=2;
g1.weightx=10;
g1.weighty=10;
c.add(new JButton("组件"),g1);
}
若缩小窗体,则会组件间的距离会缩小,空间不够时,便会回到没有设置weight属性前的状态
JPanel面板
面板本质是一个容器,必须依赖于窗体,也可以添加组件,设置布局方式,一个窗体可以有多个面板,互不干扰
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame{
public Demo(){
setBounds(200,200,500,600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container c=getContentPane();
c.setLayout(new GridLayout(2,2,10,10));
JPanel p1=new JPanel();
p1.setLayout(new GridLayout(1,3,10,10));
JPanel p2=new JPanel(new BorderLayout());
JPanel p3=new JPanel(new GridLayout(1,2,10,10));
JPanel p4=new JPanel(new GridLayout(2,1,10,10));
//两种设置布局的方式
p1.setBorder(BorderFactory.createTitledBorder("面板1"));//添加标题边框
p2.setBorder(BorderFactory.createTitledBorder("面板2"));//添加标题边框
p3.setBorder(BorderFactory.createTitledBorder("面板3"));//添加标题边框
p4.setBorder(BorderFactory.createTitledBorder("面板4"));//添加标题边框
p1.add(new JButton("p1"));
p1.add(new JButton("p1"));
p1.add(new JButton("p1"));
p1.add(new JButton("p1"));
p2.add(new JButton("p2"),BorderLayout.CENTER);
p2.add(new JButton("p2"),BorderLayout.SOUTH);
p2.add(new JButton("p2"),BorderLayout.NORTH);
p2.add(new JButton("p2"),BorderLayout.WEST);
p2.add(new JButton("p2"),BorderLayout.EAST);
p3.add(new JButton("p3"));
p3.add(new JButton("p3"));
p4.add(new JButton("p4"));
p4.add(new JButton("p"));
c.add(p1);c.add(p2);c.add(p3);c.add(p4);
setVisible(true);
}
public static void main(String[] args) {
new Demo();
}
}
JScrollPane滚动面板
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(200, 200, 500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
JTextArea area=new JTextArea();//创建文本域
JScrollPane sp=new JScrollPane(area);//创建滚动面板,给文本域添加滚动条
c.add(sp);
}
public static void main(String[] args) {
new Demo();
}
}
文本内容超出可视范围时,便会出现滚动条
提交按钮组件 JButton
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(200, 200, 500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new GridLayout(3,2,5,5));
JButton btn[]=new JButton[6];
for(int i=0;i<6;i++){
btn[i]=new JButton();
c.add(btn[i]);
}//添加6个按钮
btn[0].setText("不可用");//设置文本
btn[0].setEnabled(false);//设置不可用
btn[1].setText("有背景色");
btn[1].setBackground(Color.blue);//设置背景色
btn[2].setText("无边框");
btn[2].setBorderPainted(false);//不显示边框
btn[3].setText("有边框");
btn[3].setBorder(BorderFactory.createLineBorder(Color.red));//设置线边框
URL url=Demo.class.getResource("java.png");
Icon icon=new ImageIcon(url);
btn[4].setIcon(icon);
btn[4].setToolTipText("图片按钮");//鼠标悬停提示
btn[5].setText("可点击");
btn[5].addActionListener(new ActionListener() {//添加监听事件
public void actionPerformed(ActionEvent actionEvent) {//监听触发的方法
JOptionPane.showMessageDialog(Demo.this,"点击按钮");//弹出小对话框
}
});
}
public static void main(String[] args) {
new Demo();
}
}
按钮展示.png
Demo.this参数的意思是该对话框是在Demo类中弹出来的
单选按钮组件 JRadioButton
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(200, 200, 500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new FlowLayout());
final JRadioButton male=new JRadioButton("男");
final JRadioButton female=new JRadioButton("女");
c.add(male);
c.add(female);
final ButtonGroup group=new ButtonGroup();//按钮组
group.add(male);
group.add(female);
//male.setSelected(true);默认选中
JButton btn=new JButton("打印");
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println(male.getText()+"按钮选中状态"+male.isSelected());
System.out.println(female.getText()+"按钮选中状态"+female.isSelected());
//group.clearSelection();//清空选项
}
});
c.add(btn);
}
public static void main(String[] args) {
new Demo();
}
}
单选按钮展示.png
一定要将单选按钮放在按钮组中
复选框组件 JCheckBox
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(200, 200, 500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JCheckBox c1=new JCheckBox("a");
JCheckBox c2=new JCheckBox("b");
JCheckBox c3=new JCheckBox("c");
c.add(c1);
c.add(c2);
c.add(c3);
c1.setSelected(true);
}
public static void main(String[] args) {
new Demo();
}
}
下拉框 JComboBox
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(200, 200, 500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(null);
// 方式一 JComboBox comboBox=new JComboBox();
// comboBox.addItem(true);
// comboBox.addItem(false);
// 方式二 String items[]={"学生","老师","军人"};
// JComboBox<String> comboBox=new JComboBox<>(items);//使用String添加下拉列表元素
//方式三
JComboBox<String> comboBox=new JComboBox<>();
String items[]={"学生","老师","军人"};
ComboBoxModel cm=new DefaultComboBoxModel<>(items);//创建下拉列表模型
comboBox.setModel(cm);//添加模型
comboBox.setBounds(10,10,80,21);
c.add(comboBox);
// comboBox.getSelectedIndex();//获取选中的索引
// comboBox.getSelectedItem();//获取选中的值
// comboBox.setEditable(true);//是否可以编辑
}
public static void main(String[] args) {
new Demo();
}
}
列表框 Jlist
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(100, 100, 217, 167);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(null);
String items[] = {"元素1", "元素2", "元素3", "元素4", "元素5", "元素6", "元素7", "元素8", "元素9"};
// JList<String> jl=new JList<>(items);
DefaultListModel<String> model = new DefaultListModel<>();//列表框的数据模型
for (String temp : items) {
model.addElement(temp);//向数据模型中添加元素
}
JList<String> jl = new JList<>();
model.addElement("添加元素");//向数据模型中添加新元素
jl.setModel(model);//列表框载入数据模型
/*
* 选择模式
* SINGLE_SELECTION 单选
* SINGLE_INTERVAL_SELECTION 只能连续选择相邻的元素
* MULTIPLE_INTERVAL_SELECTION 随便选
*/
jl.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
JScrollPane js = new JScrollPane(jl);//为列表添加滚动条
js.setBounds(10, 10, 100, 100);
c.add(js);
// java.util.List<String> values=jl.getSelectedValuesList();//获取列表框中选中的所有元素
// for (String temp:values) {
// System.out.println(temp);
// }
}
public static void main(String[] args) {
new Demo();
}
}
使用模型添加新元素很方便,灵活
文本框 JTextField
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(100, 100, 217, 167);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextField jt=new JTextField(20);//设置长度
// jt.setColumns(20);//设置长度
jt.setText("afa");//设置文本内容
jt.setFont(new Font("宋体",Font.PLAIN,20));//设置字体格式
c.add(jt);
// jt.getText();//获取文本内容
// jt.setText("");//清空文本框效果
// jt.requestFocus();//获取光标
}
public static void main(String[] args) {
new Demo();
}
}
密码框 JPasswordField
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(100, 100, 217, 167);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JPasswordField jp=new JPasswordField();
jp.setColumns(20);
// jp.setFont(new Font("Arial",Font.BOLD,18));//设置字体
jp.setEchoChar('\u2605');//设置回显字符
// char ch[]=jp.getPassword();//获取密码的字符数组
// String str=new String(ch);
c.add(jp);
}
public static void main(String[] args) {
new Demo();
}
}
文本域 JTextArea
import java.awt.*;
import javax.swing.*;
public class Demo extends JFrame {
public Demo() {
setBounds(100, 100, 217, 167);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
Container c = getContentPane();
c.setLayout(new FlowLayout());
JTextArea area=new JTextArea();
// area.setFont(new Font("楷体",Font.PLAIN,20));
area.setText("这是文本域");//设定文本内容
area.setRows(5);//设定行
area.setColumns(20);//设定列数
area.append("添加内容");//在已有内容的末尾添加新内容
area.insert("插入",2);//在第二个字符的后面插入内容
JScrollPane js=new JScrollPane(area);//添加滚动条
c.add(js);
}
public static void main(String[] args) {
new Demo();
}
}