【今日】
“若你决定灿烂,山无遮,海无拦”
目录
初识Swing
一 Swing简述
二 Swing常用窗体
2.1 JFrame窗体
2.2 JDialog对话框
2.3JOptionPane小型对话框
(1)通知框
(2)确认框
(3)输入框
(4)自定义对话框
三 常用布局管理器
3.1 绝对布局
3.2 流布局
3.3 边界布局
3.4 网格布局
四 常用面板
4.1 JPanel面板
4.2 JScrollpane滚动面板
Swing用于开发桌面窗体程序,是JDK的第二代GUI框架,其功能比JDK第一代GUI框架AWT更为强大、性能更加优良。但因为Swing技术推出时间太早,其性能、开发效率等不及一些其他流行技术,所以目前市场上大多数桌面窗体程序都不是由Java开发的,Swing技术也逐渐被广大开发人员放弃了。
不过,Swing是JDK自带的功能,并且能非常好地体现Java语言在面向对象、接口事件等方面的设计模式,又能提供直观地呈现运行效果。
Swing中的大多数组件均为轻量级组件,使用Swing开发出的窗体风格会与当前平台(如Windows、Linux等)的窗体风格保持一致。
Swing主要用来开发GUI(Graphical User Interface)程序,GUI是应用程序提供给用户操作的图形界面,包括窗口、菜单、按钮等图形界面元素,我们经常使用的QQ软件、360安全卫士等均为GUI程序。Java语言为Swing程序的开发提供了丰富的类库,这些类分别被存储在java.awt和javax.swing包中。Swing提供了丰富的组件,在开发Swing程序时,这些组件被广泛地应用。
Swing组件是完全由Java语言编写的组件。因为Java语言不依赖于本地平台(即“操作系统”),所以Swing组件可以被应用于任何平台。基于“跨平台”这一特性,Swing组件被称作“轻量级组件”;反之,依赖于本地平台的组件被称作“重量级组件”,在Swing包的层次结构和继承关系中,比较重要的类是Component类(组件类)、Container类(容器类)和JComponent类(Swing组件父类)。Swing包的层次结构和继承关系如图所示。
常用的Swing组件
开发Swing程序的流程可以被简单地概括为首先通过继承javax.swing.JFrame类创建一个窗体,然后向这个窗体中添加组件,最后为添加的组件设置监听事件。
JFrame类的常用构造方法包括以下两种形式:
public JFrame():创建一个初始不可见、没有标题的窗体
public JFrame(String title):创建一个不可见、具有标题的窗体比如:创建一个不可见有标题的窗体;
JFrame f = new JFrame("窗体标题");//创建窗体对象 Container c = f.getContentPane();//获取窗体容器
在创建窗体后,先调用getContentPane()方法将窗体转换为容器,再调用add(方法或者remove()方法向容器中添加组件或者删除容器中的组件。向容器中添加按钮,关键代码如下:
JLabel l= new JLabel("这是一个窗体");//创建了一个标签 c.add(l);//添加组件 c.remove(l);//删除组件
创建窗体后,要对窗体进行设置,如设置窗体的位置、大小、是否可见等。JFrame类提供的相应方法可实现上述设置操作,具体如下:
setBounds(int x, int y, int width, int leight):设置窗体左上角在屏幕中的坐标为(x,y),窗体的宽 度为width,窗体的高度为height。 setLocation(int x,int y):设置窗体左上角在屏幕中的坐标为(x,y)。 setSize(int width, int height):设置窗体的宽度为width,高度为height。 setVisibale(boolean b):设置窗体是否可见。b为true时,表示可见;b为false时,表示不可见。
JFrame窗体关闭的几种方式
下面我们用代码来实现一个窗体程序:
【代码实列】
import java.awt.Color;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Demo {
public static void main(String[] args) {
JFrame f = new JFrame("窗体标题");//创建窗体对象
f.setVisible(true);//设置窗体可见
/*
* 窗体关闭规则
* EXIT_ON_CLOSE:隐藏窗体,并停止程序
* DO_NOTHING_ON_CLOSE:无任何操作
* HIDE ON_ CLOSE:隐藏窗体,但不停止程序
* DISPOSE_ ON_CLOSE:释放窗体资源
*/
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(300, 200);//设置窗体的大小,单位:像素
f.setLocation(400, 300);//设置窗体的位置,单位:像素
/*
* f.setBounds(x, y, 长, 高);//可以用一句代替上面的两句
*/
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);//设置窗体是否可以改变大小
System.out.println("窗体的位置:x="+f.getX()+" y="+f.getY());
}
}
但在实际中我们一般会直接继承JFrame,不在单独创建对象,初学者可以先了解一下:
import java.awt.Color; import java.awt.Container; import javax.swing.JFrame; import javax.swing.JLabel; public class Demo extends JFrame{//让Demo类也成为一个窗体 public Demo(){ setVisible(true);//设置窗体可见 setTitle("窗口标题"); /* * 窗体关闭规则 * EXIT_ON_CLOSE:隐藏窗体,并停止程序 * DO_NOTHING_ON_CLOSE:无任何操作 * HIDE ON_ CLOSE:隐藏窗体,但不停止程序 * DISPOSE_ ON_CLOSE:释放窗体资源 */ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300, 200);//设置窗体的大小,单位:像素 setLocation(400, 300);//设置窗体的位置,单位:像素 /* * f.setBounds(x, y, 长, 高);//可以用一句代替上面的两句 */ Container c = getContentPane();//获取窗体容器 c.setBackground(Color.WHITE);//设置背景颜色 JLabel l= new JLabel("这是一个窗体");//创建了一个标签 c.add(l);//添加组件 // c.remove(l);//删除组件 c.validate();//验证容器中的组件(相当于刷新操作) // setContentPane(c);重新载入容器(相当于刷新操作) setResizable(false);//设置窗体是否可以改变大小 System.out.println("窗体的位置:x="+getX()+" y="+getY()); } public static void main(String[] args) { new Demo(); } }
Dialog对话框继承了java.awt.Dialog类,其功能是从一个窗体 中弹出另一个窗体,如使用IE浏览器时弹出的确定对话框。JDialog对话框与JFrame窗体类似,被使用时也需要先调用getContentPane()方法把JDialog对话框转换为容器,再对JDialog对话框进行设置。
public JDialog():创建一个没有标题和父窗体的对话框。
public JDialog(Frame f):创建一个没有标题,但指定父窗体的对话框。
public JDialog(Frame f, boolean model):创建一个没有标题,但指定父窗体和模式的对话框。如果model为true,那么弹出对话框后,用户无法操作父窗体。
public JDialog(Frame f, String title):创建一个指定标题和父窗体的对话框。
public JDialog(Frame f, String title, boolean model):创建一个指定标题、父窗体和模式的对话框。
【代码实列】
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Demo extends JDialog{
public Demo(JFrame frame) {
/*
* 第一个参数是父窗体对象
* 第二个参数是对话框标题
* 第三个参数是是否阻塞父窗体
* true为阻塞,false为不阻塞
*/
super(frame, "对话框标题", true);
//第一个传入frame对象(父窗体)
Container c = getContentPane();//获取窗体容器
c.add(new JLabel("这是一个窗体对话框"));
setBounds(100, 100, 100, 100);
}
public static void main(String[] args) {
JFrame f =new JFrame("父窗体");
f.setBounds(50, 50, 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() {
//创建了一个匿名对象
@Override
public void actionPerformed(ActionEvent e) {
// 这个方法就是点击按钮以后会运行的方法
Demo d =new Demo(f);
d.setVisible(true);//设置窗体可见
}
});//添加动作监听
}
}
【运行效果】
Java API中的javax.swing.JOptionPane类是一个非常简便的小型对话框类,该类用于创建对话框的方法都是静态方法,无须创建对象即可弹出。在日常开发中经常使用该类弹出提示、确认用户需求、调试程序等。JOptionPane提供了4种创建对话框的方法 ,如表所示:
通知框是最简单的一个对话框,仅弹出提示,不会返回任何值。
1.样式:
2.创建通知框的代码块:
showMessageDialog(Component parentComponent,//在那个窗口弹出 object message, //通知什么内容 String title, //标题 int message Type) //通知框的风格
3.通知框的风格:
【代码实列】
import javax.swing.JOptionPane;
public class Demo {
public static void main(String[] args) {
JOptionPane.showMessageDialog(null,
"您与服务器断开连接",
"发生错误",
JOptionPane.WARNING_MESSAGE);
}
}
【运行效果】
WARNING_MESSAGE:
WARNING_MESSAGE:
确认框已经封装好了一套外观样式,弹出后要求用户做选择操作,用户选择具体选项后,确认框可以返回用户的选择结果,结果以int方式返回。
2.创建确认框的代码块:
showConfirmDialog(Component parentComponent,//在那个窗口弹出 object message, //通知什么内容 String title, //标题 int message Type) //通知框的风格
3.通知框的风格:
YES_NO_CANCEL_OPTION:3键
YES_NO_OPTION:2键
【代码实列】
import javax.swing.JOptionPane;
public class Demo {
public static void main(String[] args) {
JOptionPane.showConfirmDialog(null,
"确定离开吗?",
"提示",
JOptionPane.YES_NO_CANCEL_OPTION);
}
}
【运行效果】
YES_NO_OPTION:
因为该确认窗可以返回结果,所以我们可以通过结果判断用户的选择:
是:0 否:1 X:-1 取消:2
输入框已经封装好了一套外观样式,弹出后要求用户在文本框中输入文本,用户完成输入操作后,
输入框可以返回用户输入的结果.
1.样式:
2.创建输入框的代码块:
showInputDialog(Component parentComponent, //在那个窗口弹出 Object message, //通知什么内容 String title, //标题 int messageType) //输入框的风格
【代码实列】
import javax.swing.JOptionPane;
public class Demo {
public static void main(String[] args) {
String name =JOptionPane.showInputDialog(null,
"请输入你的姓名");
System.out.println(name);
}
}
【运行效果】
自定义对话框模板:
showOptionDialog(Component parentComponent,//在哪个窗体弹出 Object message, //通知什么内容? String title, //标题 int optionType, //选项类型,可定义按钮风格 int messageType, //消息类型,可定义外观风格 Icon icon, //图标 Object[] options, //有哪些组件 Object initialValue) //默认选中的组件
在下面自定义中我们会用到这个图标:
【代码实列】
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
public class Demo {
public static void main(String[] args) {
Icon icon = new ImageIcon("src/注意.png");//获得图标
JButton b1 = new JButton("是的");//创建组件按钮b1
JButton b2 = new JButton("再想想");//创建组件按钮b2
Object os[] = {b1,b2};
JOptionPane.showOptionDialog(null,
"你准备好了吗?",
"注意了",
JOptionPane.DEFAULT_OPTION,
JOptionPane.DEFAULT_OPTION,
icon,
os,
null);
}
}
【运行效果】
开发Swing程序时,在容器中使用布局管理器能够设置窗体的布局,进而控制Swing组件的位置大小。Swing 常用的布局管理器为绝对布局管理器、流布局管理器、边界布局管理器和网格布局管器。
绝对布局也叫null布局,其特点是硬性指定组件在容器中的位置和大小,组件的位直通过绝对坐 标的方式来指定。使用绝对布局首先要使用Container.setLayout(null)方法取消容器的布局管理器,然后再使用Component.setBounds(int x,int y,int width, int height)方法设置每个组件在容器中的位置和大小。
【实列代码】
import java.awt.Container;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setTitle("标题");//设置标题
setBounds(100, 300,800, 400);//设置位置以及大小
setVisible(true);//设置窗体是否可见
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭方式
Container c = getContentPane();//设置容器
c.setLayout(null);//设置为null布局
JButton b1 = new JButton("按钮1");//设置按钮
JButton b2 = new JButton("按钮2");
b1.setBounds(10, 20, 100, 50);
b2.setBounds(400, 20, 100, 50);
c.add(b1);
c.add(b2);
}
public static void main(String[] args) {
Demo d = new Demo();
}
}
【运行结果】
注意:
绝对布局不具备弹性,页面元素的位置和尺寸无法基于内容或用户需求进行自适应调整。这可能导致在内容不同或窗口大小变化时产生剪切、溢出或显示问题。绝对布局里面的按钮位置不会因为窗体的大小改变位置而发生改变,如图所示:
流布局(FlowLayout)管理器是Swing中最基本的布局管理器。使用流布局管理器摆放组件时,组件被从左到右摆放。当组件占据了当前行的所有空间时,溢出的组件会被移动到当前行的下一行。默认情况下,行组件的排列方式被指定为居中对齐,但是通过设置可以更改每一行组件的排列方式。
FlowLayout的三种构造方法:
FloyLayout(); // 默认构造方法FloyLayout(int alignment); //
FloyLayout(int alignment int horizGap,int vertGap);
//对齐方式 水平间距 垂直间距
对齐方式:
FlowLayout.LEFT //左对齐FlowLayout.RIGHT //右对齐
FlowLayout.CENTER //居中对齐
【代码实列】
import java.awt.Container;
import java.awt.FlowLayout;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setTitle("标题");//设置标题
setBounds(100,100,300,200);//设置位置以及大小
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭方式
Container c = getContentPane();//设置容器
c.setLayout(new FlowLayout());//设置为流布局
for(int i=0;i<=9;i++) {
c.add(new JButton("按钮"+i));
}
setVisible(true);//设置窗体是否可见
}
public static void main(String[] args) {
Demo d = new Demo();
}
}
【运行结果】
使用 Swing创建窗体后,容器默认的布局管理器是边界布局(BorderLayout)管理器,边界布局管理器把容器划分为东、南、西、北、中5个区域,如图所示。
当组件被添加到被设置为边界布局管理器的容器时,需要使用BorderLayout类中的成员变量指定被添加的组件在边界布局管理器中的区域,BorderLayout类中的成员变量及其说明如下表:
【代码实列】
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setTitle("边界布局");//设置标题
setBounds(100,100,300,200);//设置位置以及大小
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭方式
Container c = getContentPane();//设置容器
c.setLayout(new BorderLayout());//设置为边界布局
JButton b1 = new JButton("中");
JButton b2 = new JButton("东");
JButton b3 = new JButton("西");
JButton b4 = new JButton("南");
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) {
Demo d = new Demo();
}
}
【运行结果】
注意:
在同一个区域反复添加元素时,新元素会覆盖旧元素。当窗体长足够小是,只有南北按钮。
网格布局(GridLayout)管理器能够把容器划分为网格,组件可以按行、列进行排列。在网格布局管理器中,网格的个数由行数和列数决定,且每个网格的大小都相同。例如,一个两行两列的网格布局管理器能够产生4个大小相等的网格。组件从网格的左上角开始,按照从左到右、从上到下的顺序被添加到网格中,且每个组件都会填满整个网格。改变窗体大小时,组件的大小也会随之改变。
两种构造方法:
【代码实列】
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setTitle("网格布局");//设置标题
setBounds(100,100,300,300);//设置位置以及大小
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭方式
Container c = getContentPane();//设置容器
c.setLayout(new GridLayout(4,5));//
for(int i=0;i<20;i++) {
c.add(new JButton("按钮"+i));
}
setVisible(true);//设置窗体是否可见
}
public static void main(String[] args) {
Demo d = new Demo();
}
}
【运行结果】
在Swing程序设计中,面板是一个容器,背用于容纳其他组件,但面板必须被添加到其他容器中。
Jpanel面板继承java.awt.Container类。JPanel面板必须在窗体容器中使用,无法脱离窗体显示。
初始化一个面板的方法:
Jpanel p = new JPanel(new 布局方法);
使用JPanel可以将其他Swing组件添加到其中。使用JPanel的setLayout()方法可以设置布局管理器来控制组件在面板中的放置方式。
【代码实列】
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setTitle("面板");//设置标题
setBounds(100,100,500,300);//设置位置以及大小
setDefaultCloseOperation(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));
/*
* 给每个面板添加边框和标题,使用BorderFactory工厂类生成带标题的
* 边框对象
*/
p1.setBorder(BorderFactory.createTitledBorder("面板一"));//添加标题边框
p2.setBorder(BorderFactory.createTitledBorder("面板二"));
p3.setBorder(BorderFactory.createTitledBorder("面板三"));
p4.setBorder(BorderFactory.createTitledBorder("面板四"));
/*
* 添加按钮
*/
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.EAST);
p2.add(new JButton("P2"), BorderLayout.WEST);
p2.add(new JButton("P2"), BorderLayout.NORTH);
p2.add(new JButton("P2"), BorderLayout.SOUTH);
p3.add(new JButton("P3"));
p3.add(new JButton("P3"));
p4.add(new JButton("p4"));
p4.add(new JButton("p4"));
/*
* 将面板添加到容器中
*/
c.add(p1);
c.add(p2);
c.add(p3);
c.add(p4);
setVisible(true);//设置窗体可见
}
public static void main(String[] args) {
Demo d = new Demo();
}
}
【运行结果】
JScrollpane滚动面板是带滚动条的面板,被用于在较小的窗体中显示较大的篇幅的内容。
【代码实列】
import java.awt.Container;
import javax.swing.*;
public class Demo extends JFrame{
public Demo() {
setBounds(100,100,500,300);//设置位置以及大小
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置窗体关闭的方式
Container c = getContentPane();
JTextArea Jt = new JTextArea();//创建了一个文本域
JScrollPane Js = new JScrollPane(Jt);//创建滚动面板,给文本域添加滚动条
c.add(Js);
setVisible(true);//设置窗体可见
}
public static void main(String[] args) {
new Demo();
}
}
【运行效果】