AWT(Abstract Window Toolkit)和Swing 是 Java 提供的用于创建图形用户界面(GUI)的类库。
AWT:AWT 是 Java 最早提供的 GUI 类库,它基于本地平台的窗口系统,使用操作系统的原生组件进行界面渲染。AWT 提供了一系列的类和方法,用于创建窗口、按钮、文本框等 GUI 组件,并处理用户事件。AWT 的组件和事件模型与底层平台密切相关,因此在不同的平台上可能会有差异。
Swing:Swing 是建立在 AWT 之上的一个 GUI 类库,它完全由 Java 编写,不依赖于底层平台。Swing 提供了一套丰富的可定制的轻量级组件,如 JFrame、JButton、JTextField 等,并且具有更好的外观和跨平台的一致性。Swing 的组件和事件模型相对于 AWT 更加灵活,可以自定义绘制和样式。
区别:
组件外观:AWT 使用本地平台的原生组件,而 Swing 使用纯 Java 实现的组件。因此,Swing 组件的外观更加统一,并且可以自定义绘制和样式,而 AWT 组件外观受限于本地平台。
跨平台性:由于 Swing 是纯 Java 实现的,它的外观和行为在不同平台上是一致的,而 AWT 的外观和行为可能因平台而异。
功能扩展:Swing 提供了更多的组件和功能,例如树状组件、表格组件等。同时,Swing 也支持更多的布局管理器,可以实现更复杂的界面布局。
关于 Frame 和 JFrame:
Frame:Frame 是 AWT 中的一个顶层窗口类,继承自 Window 类。它是一个简单的窗口容器,可以用来创建应用程序的主窗口。Frame 可以包含其他的组件,如按钮、文本框等。
JFrame:JFrame 是 Swing 中的一个顶层窗口类,继承自 Frame 类。JFrame 拥有更丰富的特性和功能,例如可自定义的标题栏、菜单栏、工具栏等。同时,JFrame 也支持 Swing 的 Look and Feel,可以统一外观,并且可以进行更灵活的界面定制。
总体上,AWT 是 Java 最早的 GUI 类库,基于本地平台的原生组件,而 Swing 是建立在 AWT 之上的一套完全由 Java 实现的 GUI 类库,提供了更丰富的组件和功能,同时具备跨平台性和可定制性。Frame 是 AWT 的顶层窗口类,而 JFrame 是 Swing 的顶层窗口类,JFrame 比 Frame 提供了更多的特性和功能。
总结:AWT是基础,Swing是以AWT为基础的GUI类库。基本上就是以学习Swing为主了。
但是这并不意味着不用学AWT了,先学AWT有了基础之后,学Swing事半功倍。
抽象窗口工具
1.包含了很多类和接口。
2.元素:窗口,按钮,文本框
3.包是java.awt
简单的创建一个窗户
public class TestGUI {
public static void main(String[] args) {
Frame frame= new Frame("java图形界面窗口");
//窗口是Frame类
//需要设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(400,400);
//设置背景颜色
frame.setBackground(new Color(85,150,68));//r,g,b
//弹出的初始位置
frame.setLocation(200,200);
//设置窗口大小固定
frame.setResizable(false);
//false是不可以改变
//不写的话默认为true,可改变
}
想创建一个窗口要写这么多代码,很麻烦,我们可以自己写一个类继承Frame,然后写一些方法,便于创造多个窗口
class MyFrame extends Frame{
static int id = 0;//可能存在多个窗口,我们需要一个计数器
public MyFrame(int x,int y,int w,int h,Color c) {
super("MyFrame"+(++id));//调用父类的构造方法
setBackground(c);
setBounds(x,y,w,h);//等同于setLocation和setSize的结合
setVisible(true);
}
}
public class TestGUI {
public static void main(String[] args) {
MyFrame f1 = new MyFrame(100,100,200,200,Color.blue);
MyFrame f2 = new MyFrame(100,100,200,200,Color.black);
MyFrame f3 = new MyFrame(100,100,200,200,Color.cyan);
MyFrame f4 = new MyFrame(100,100,200,200,Color.green);
MyFrame f5 = new MyFrame(100,100,200,200,Color.red);
}
}
Panel可以看成是一个空间,但是不能单独存在,需要内嵌在Frame里、
以下代码实现内嵌panel,还有创建一个监听事件->监听窗口关闭事件
public class TestGUI {
public static void main(String[] args) {
Frame frame = new Frame();
//布局的概念
//可以内嵌一个个面板
Panel panel = new Panel();
//设置布局,下一块内容详细介绍
frame.setLayout(null);//流布局
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(40,161,35));
//设置panel坐标(相对于frame)
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(193,15,60));
//在frame中加入该面板
frame.add(panel);
frame.setVisible(true);
//创建一个监听事件->监听窗口关闭事件 System.exit(0)
//这种写法显然太臃肿了,要重写所有方法
//但我们现在只想关闭窗口,所以只需要windowClosing这个方法
/*frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub
}
@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub
}
});*/
//因此我们可以用,适配器模式,只对我们需要的方法进行重写
frame.addWindowListener(new WindowAdapter() {
@Override
//在这个方法里写,窗口关闭的时候要做的事情
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
System.exit(0);
}
});
}
}
适配器模式
有以下几种布局
这里引入Button,来体现布局
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Frame frame = new Frame();
frame.setVisible(true);
frame.setBounds(400,400,400,400);
frame.setBackground(Color.GREEN);
frame.setLayout(new FlowLayout(FlowLayout.CENTER));//可以选择左右上下中
Button b1 = new Button("b1");
Button b2 = new Button("b2");
Button b3 = new Button("b3");
Button b4 = new Button("b4");
Button b5 = new Button("b5");
frame.add(b1);
frame.add(b2);
frame.add(b3);
frame.add(b4);
frame.add(b5);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Frame frame = new Frame("TestBorderLayout");
frame.setVisible(true);
frame.setBounds(400,400,400,400);
frame.setBackground(Color.GREEN);
Button east = new Button("east");
Button west = new Button("west");
Button south = new Button("south");
Button north = new Button("north");
Button center = new Button("center");
frame.add(center,BorderLayout.CENTER);
frame.add(east,BorderLayout.EAST);
frame.add(west,BorderLayout.WEST);
frame.add(north,BorderLayout.NORTH);
frame.add(south,BorderLayout.SOUTH);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Frame frame = new Frame("TestBorderLayout");
frame.setVisible(true);
frame.setBounds(400,400,400,400);
frame.setBackground(Color.GREEN);
Button b1 = new Button("b1");
Button b2 = new Button("b2");
Button b3 = new Button("b3");
Button b4 = new Button("b4");
Button b5 = new Button("b5");
Button b6 = new Button("b6");
frame.setLayout(new GridLayout(3,2));//核心代码
frame.add(b1);
frame.add(b2);
frame.add(b3);
frame.add(b4);
frame.add(b5);
frame.add(b6);
//frame.pack();//自动填充,也可以不用
}
}
设计下图窗口
package demo;
import java.util.*;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.Random;
import java.util.Arrays;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.*;
import java.awt.event.*;
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
Frame frame = new Frame("ExDemo");
frame.setVisible(true);
frame.setBounds(400,400,800,500);
frame.setLayout(new GridLayout(2,1));
//先写上面的
Panel p1 = new Panel(new BorderLayout());
//要用边界布局,后续在p1里布置东,西,中
Panel p2 = new Panel(new GridLayout(2,1));
p1.add(new Button("west-1"),BorderLayout.WEST);
p1.add(new Button("east-1"),BorderLayout.EAST);
p2.add(new Button("p2-btn-1"));
p2.add(new Button("p2-btn-2"));
p1.add(p2,BorderLayout.CENTER);
//再写下面的
Panel p3 = new Panel(new BorderLayout());
Panel p4 = new Panel(new GridLayout(2,2));
p3.add(new Button("west-2"),BorderLayout.WEST);
p3.add(new Button("east-2"),BorderLayout.EAST);
for(int i = 1;i<=4;i++) {
p4.add(new Button("p4-btn-"+i));
}
p3.add(p4,BorderLayout.CENTER);
frame.add(p1);
frame.add(p3);
}
}
JFrame:JFrame 是 Swing 中的一个顶层窗口类,继承自 Frame 类。
这意味着Frame的操作和方法基本在JFrame都能用,但有些还是有所区别的。
例如:Frame可以用setBackground设置背景颜色,而JFrame不行,
在Swing中,JFrame是继承自Frame的顶层窗口组件,但是它重写了父类Frame的设置背景颜色的方法。在JFrame中并没有提供直接设置背景颜色的方法,因为Swing更多地依赖于Look and Feel和视觉外观管理器(UIManager)来控制组件的外观和感觉。因此,想要设置JFrame的背景颜色,通常需要使用其他组件或技术来实现,比如在contentPane上添加一个背景色为指定颜色的面板。
接下来开始正式介绍了
无参构造
JFrame jf = new JFrame();
jf.setTitle("TestJF");
有参构造
JFrame jf = new JFrame("TestJF");
无参构造可以配合setTitle来设置标题
setTitle("窗体名称");
用来设置窗口名字①setSize(int width, int height);
这个方法用来设置窗体的大小,传入宽高即可。②setLocation(int x, int y);
这个方法用来设置窗体的坐标(原点在左上角),传入坐标即可。③setBounds(int x, int y, int width, int height);
看这玩意的参数你就大概猜得到,没错它就是上面②和①的整合版。④setVisible(boolean b);
用来设置窗体是否可见,默认是不可见的,所以要可见必须用这个方法传入参数true。⑤setDefaultCloseOperation(int opreation);
用来设置点击窗体关闭按钮的时候,做出的响应。通常都是如下面这样写(调用WindowConstants这个类中的静态成员EXIT_ON_CLOSE,表示点击关闭按钮时的默认响应为关闭此窗口并结束程序)。fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
WindowConstants的相关静态成员如下:DO_NOTHING_ON_CLOSE(什么也不做)
HIDE_ON_CLOSE (隐藏当前窗口)
DISPOSE_ON_CLOSE (隐藏当前窗口,并释放窗体占有的其他资源,这个重点记一下,后面讲JDialog会用到)
EXIT_ON_CLOSE (结束窗口所在的应用程序)。
?
创建一个窗口
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("TestJF");
jf.setBounds(400,400,400,400);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("TestJF");
jf.setTitle(null);
jf.setVisible(true);
jf.setBounds(400,400,400,400);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JDialog jd = new JDialog(jf,"TestJD");
jd.setBounds(450,450,100,100);
jd.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
jd.setModal(true);//设置模态窗口
jd.setVisible(true);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("Test");
jf.setBounds(400,400,400,400);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
JPanel p = new JPanel();
JButton b1 = new JButton("b1");
JButton b2 = new JButton("b2");
JButton b3 = new JButton("b3");
JButton b4 = new JButton("b4");
p.add(b1);p.add(b2);p.add(b3);p.add(b4);
jf.add(p);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("Test");
jf.setBounds(400,400,400,400);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
JPanel p = new JPanel();
JButton b1 = new JButton("b1");
JButton b2 = new JButton("b2");
JButton b3 = new JButton("b3");
JButton b4 = new JButton("b4");
p.add(b1);p.add(b2);p.add(b3);p.add(b4);
jf.add(p);
JScrollPane jsp = new JScrollPane();
jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
jsp.setViewportView(p);
jf.add(jsp);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("Test");
jf.setBounds(400,400,400,400);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
JPanel p = new JPanel();
JLabel label = new JLabel("插入标签");
p.add(label);
jf.add(p);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("Test");
jf.setBounds(400,400,500,500);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
JPanel p = new JPanel();
JTextField jt = new JTextField(40);//设置文本框列数,也就是设置长度
p.add(jt);
jf.add(p);
}
}
public class Main {
public static void main(String[] args) throws InterruptedException, ExecutionException {
JFrame jf = new JFrame("Test");
jf.setBounds(400,400,500,500);
jf.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
jf.setVisible(true);
JPanel p = new JPanel();
JTextArea jt = new JTextArea(5,20);//设置文本框列数,也就是设置长度
p.add(jt);
jf.add(p);
}
}
跟AWT的Button没什么区别,不赘述了
public class Main {
public static void createGUI() {
JFrame fr = new JFrame("这是主窗口");//通常直接在有参构造的时候命名,省得后续用setTitle()方法命名了。
fr.setSize(400, 250);//设置窗体宽高
fr.setLocation(400, 300);//设置窗体坐标
fr.setVisible(true);//设置窗体可见,基本必写吧?
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗体关闭按钮响应事件为关闭此窗口。
//以下是重点
JPanel pane = new JPanel();
JLabel label = new JLabel("请输入:");
JTextField textField = new JTextField(20);
JButton button = new JButton("发送");
pane.add(label);
pane.add(textField);
pane.add(button);
//把容器放在窗口中
fr.add(pane);
}
public static void main(String[] args) {
createGUI();
}
}
重点掌握:实现ActionListener这个接口,并重写其中的actionPerformed方法(这个方法就固定接收一个ActionEvent类)
例如:
class my_listenr implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {//传入的参数是事件
// TODO Auto-generated method stub
System.out.println("按钮被点击");
}
}
实现一个功能,点击按钮,会输出“按钮被点击”.
class my_listenr implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {//传入的参数是监听事件
// TODO Auto-generated method stub
System.out.println("按钮被点击");
}
}
public class Main {
public static void createGUI() {
JFrame fr = new JFrame("这是主窗口");//通常直接在有参构造的时候命名,省得后续用setTitle()方法命名了。
fr.setSize(400, 250);//设置窗体宽高
fr.setLocation(400, 300);//设置窗体坐标
fr.setVisible(true);//设置窗体可见,基本必写吧?
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗体关闭按钮响应事件为关闭此窗口。
JPanel p = new JPanel();
JButton b = new JButton("按钮");
b.addActionListener(new my_listenr());
p.add(b);fr.add(p);
}
public static void main(String[] args) {
createGUI();
}
}
实际上,每个按钮的功能一般都不一样,如果有多个按钮,用方法一的话就要自定义多个类,太冗余了,因此我们可以用匿名内部类实现。
对这个知识点不熟悉的可以看->?匿名内部类
public class Main {
public static void createGUI() {
JFrame fr = new JFrame("这是主窗口");//通常直接在有参构造的时候命名,省得后续用setTitle()方法命名了。
fr.setSize(400, 250);//设置窗体宽高
fr.setLocation(400, 300);//设置窗体坐标
fr.setVisible(true);//设置窗体可见,基本必写吧?
fr.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//设置窗体关闭按钮响应事件为关闭此窗口。
JPanel p = new JPanel();
JButton b = new JButton("按钮");
//匿名内部类实现
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("按钮被点击");
}
});
p.add(b);fr.add(p);
}
public static void main(String[] args) {
createGUI();
}
}
效果与方法一相同