GUI的核心技术 Swing 和 AWT
1. AWT介绍
AWT:抽象的窗口工具
GUI:图形用户界面编程
元素:窗口、按钮、文本框
2. 新建一个窗口
关键字 Frame
查看Frame源码(左键+Ctrl点击Frame),看左侧idea,可以看到Frame能接收的几种参数:
直接上代码:
import java.awt.*;
//第一个GUI界面
public class TestFrame {
public static void main(String[] args) {
Frame frame = new Frame("我的第一个Java图形界面");
//设置可见性
frame.setVisible(true);
//设置窗口大小
frame.setSize(400,400);
//设置背景颜色
frame.setBackground(new Color(239, 10, 109));
//设置窗口弹出位置
frame.setLocation(300,300);
//设置窗口大小不可变
frame.setResizable(false);
}
}
效果图:
问题:发现窗口无法关闭,只能通过停止程序运行来关掉
问题:如何一次生成多个窗口呢?
进行类的封装,继承Frame类
import java.awt.*;
//展示多个窗口
public class Test {
public static void main(String[] args) {
MyFrame myFrame1 = new MyFrame(400, 400, 500, 500, Color.red);
MyFrame myFrame2 = new MyFrame(400,400,600,600,Color.green);
MyFrame myFrame3 = new MyFrame(400,400,900,900,Color.blue);
}
}
class MyFrame extends Frame {
static int id = 0;//进行窗口计数
//构造函数(接收自定义窗口所需的值)
public MyFrame(int x, int y, int w, int h, Color color) {
super("窗口" + (id++));
setBounds(x, y, w, h);
setBackground(color);
setVisible(true);
}
}
效果图:
3. Panel面板
直接上代码:
import java.awt.*;
//Panel不能单独存在,要和Frame搭配使用
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame();
//布局概念,Panel默认流布局
Panel panel = new Panel();
//清空Frame的默认布局
frame.setLayout(null);
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(30, 239, 232, 255));
//设置Panel相对于Frame的坐标
panel.setBounds(50,50,400,400);
panel.setBackground(new Color(206, 13, 13));
//将Panel添加到Frame中
frame.add(panel);
//设置Frame可见性
frame.setVisible(true);
}
}
问题:
在写frame.add();的时候,发现add后面的参数不是panel,那么为什么里面可以写panel呢,查看源码
原来是panel的父类继承了add后面的参数Component
panel的父类:
Container的父类:
–
监听事件,监听窗口关闭(使用AWT实现):
//为窗口添加监听事件
//重写WindowListener事件
frame.addWindowListener(new WindowListener() {
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
});
用这种方法可以实现监听,但是出现了一些不太需要的代码,如何精简代码呢?
解决方法:使用WindowAdapter,只要去重写某一个监听事件:
稍稍看一下源码:
发现WindowAdapter已经实现了WindowListener的接口,所以实现了同样的功能。
上源码:
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//Panel不能单独存在,要和Frame搭配使用
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame();
//布局概念,Panel默认流布局
Panel panel = new Panel();
//清空Frame的默认布局
frame.setLayout(null);
frame.setBounds(300, 300, 500, 500);
frame.setBackground(new Color(30, 239, 232, 255));
//设置Panel相对于Frame的坐标
panel.setBounds(50, 50, 400, 400);
panel.setBackground(new Color(206, 13, 13));
//将Panel添加到Frame中
frame.add(panel);
//设置Frame可见性
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter() {
//窗口点击关闭时触发的事件
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.out.println("窗口关闭");
System.exit(0);
}
});
}
}
4. 3种布局管理器
1. 流式布局 FlowLayout
新组件:Button
传参为按钮显示的字:
//按钮组件
Button btn1 = new Button("按钮1");
Button btn2 = new Button("按钮2");
Button btn3 = new Button("按钮3");
全部源码:
import java.awt.*;
public class TestFlowLayout {
public static void main(String[] args) {
Frame frame = new Frame();
//按钮组件
Button btn1 = new Button("按钮1");
Button btn2 = new Button("按钮2");
Button btn3 = new Button("按钮3");
//设置为流式布局
frame.setLayout(new FlowLayout());
frame.setSize(500,500);
frame.add(btn1);
frame.add(btn2);
frame.add(btn3);
frame.setVisible(true);
}
}
但是出现问题了,按钮的汉字无法显示:
网上小查了一下,发现实现按钮除了Button组件还有个JButton(属于swing)组件,这个JButton组件对中文很友好,来看一下效果:
改动的代码,保留几个Button组件作对比
–
实现了一种流式布局,发现默认流式布局是居中流式,看一下源码:
发现流式布局默认是Center显示:
继续深入:发现是已经定义好的常量,可以通过传参控制流式布局的方式
更改一下流式布局方式:
//设置为流式布局
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
效果如图:
–
2. 边界布局 BorderLayout
直接看效果吧:
import java.awt.*;
public class TestBorderLayout {
public static void main(String[] args) {
Frame frame = new Frame("TestBorderLayout");
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(East, BorderLayout.EAST);
frame.add(West, BorderLayout.WEST);
frame.add(South, BorderLayout.SOUTH);
frame.add(North, BorderLayout.NORTH);
frame.add(Center, BorderLayout.CENTER);
frame.setSize(500, 500);
frame.setVisible(true);
}
}
–
3. 表格布局 GridLayout
直接上效果图:
代码:
import java.awt.*;
//表格布局
public class TestGridLayout {
public static void main(String[] args) {
Frame frame = new Frame();
//按钮组件
Button btn1 = new Button("btn1");
Button btn2 = new Button("btn2");
Button btn3 = new Button("btn3");
Button btn4 = new Button("btn4");
Button btn5 = new Button("btn5");
Button btn6 = new Button("btn6");
//设置表格布局,并设置3行2列
frame.setLayout(new GridLayout(3,2));
frame.add(btn1);
frame.add(btn2);
frame.add(btn3);
frame.add(btn4);
frame.add(btn5);
frame.add(btn6);
frame.setSize(500,500);
frame.setVisible(true);
}
}
–
小练习:
使用布局实现如下图的界面
逐步分析:
首先上下分析此界面
先使用表格布局,为frame定义一个2行一列的界面,如上图所示。
代码:
Frame frame = new Frame();
frame.setLayout(new GridLayout(2, 1));
主题框架定下来,分别实现上下两个界面,在这里我们使用Panel
我们先实现上面的界面
再次分析:先将中间的两个按钮看做一个整体,然后一共三个组件
我们可以使用边界布局BorderLayout来实现,位置分别是WEST、EAST、CENTER
下一步,我们使用两个Panel,一个Panel(p2)实现左和右按钮的显示,一个Panel(p1)负责中间部分的显示,中间部分的Panel还负责显示一个利用表格布局实现的两个按钮,最后将显示中间按钮的Panel放在上一个Panel上,并使用边界布局的Center:
这部分的代码:
Panel p1 = new Panel(new GridLayout(2, 1));
Panel p2 = new Panel(new BorderLayout());
p1.add(new Button("p1-grid-btn1"));
p1.add(new Button("p1-grid-btn2"));
p2.add(new Button("p2-Border-West"), BorderLayout.WEST);
p2.add(new Button("p2-Border-East"), BorderLayout.EAST);
p2.add(p1, BorderLayout.CENTER);
下面的界面实现大致与上面一部分相同,唯一不同的地方是中间的Panel(p3),在这里使用的2行2列的表格布局,实现显示4个按钮:
代码:
Panel p3 = new Panel(new GridLayout(2, 2));
Panel p4 = new Panel(new BorderLayout());
//使用for循环实现4个按钮
for (int i = 0; i < 4; i++) {
p3.add(new Button("for"+i));
}
p4.add(new Button("p4-Border-West"), BorderLayout.WEST);
p4.add(new Button("p4-Border-East"), BorderLayout.EAST);
p4.add(p3, BorderLayout.CENTER);
最后一步,将两个Panel,p2和p4添加到frame上。
总体代码:
import java.awt.*;
public class Test {
public static void main(String[] args) {
Frame frame = new Frame();
frame.setLayout(new GridLayout(2, 1));
Panel p1 = new Panel(new GridLayout(2, 1));
Panel p2 = new Panel(new BorderLayout());
Panel p3 = new Panel(new GridLayout(2, 2));
Panel p4 = new Panel(new BorderLayout());
p1.add(new Button("p1-grid-btn1"));
p1.add(new Button("p1-grid-btn2"));
p2.add(new Button("p2-Border-West"), BorderLayout.WEST);
p2.add(new Button("p2-Border-East"), BorderLayout.EAST);
p2.add(p1, BorderLayout.CENTER);
//使用for循环实现4个按钮
for (int i = 0; i < 4; i++) {
p3.add(new Button("for"+i));
}
p4.add(new Button("p4-Border-West"), BorderLayout.WEST);
p4.add(new Button("p4-Border-East"), BorderLayout.EAST);
p4.add(p3, BorderLayout.CENTER);
frame.add(p2);
frame.add(p4);
frame.setSize(500, 500);
frame.setVisible(true);
}
}
最终效果:
注意:按钮上的文字长度也会影响按钮的大小。
小结:
1.一个窗口只有一个Frame
2.Panel不能独立存在,要和Frame配合使用
3.布局管理器
1.流式布局
2.边界布局
3.表格布局
5. 事件监听
ActionListener
为按钮添加了一个监听事件
代码:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//事件监听
public class ActionListener {
public static void main(String[] args) {
Frame frame = new Frame();
Button button = new Button("btn");
//myActionListener是自定义的一个连接ActionLinister接口的类,也可以直接写在button.addActionListener();中
//这里我们对他进行了一些简单的封装
MyActionListener myActionListener = new MyActionListener();
button.addActionListener(myActionListener);
//使用了封装的监听窗口关闭的方法
WidowClos(frame);
frame.add(button);
frame.setSize(500, 500);
frame.setVisible(true);
}
public static void WidowClos(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口关闭了");
System.exit(0);
}
});
}
}
class MyActionListener implements java.awt.event.ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("按钮监听事件");
}
}
–
实现两个按钮公用一个监听事件:
通过 e.getActionCommand() 能够获取到按键的信息,从而判断是哪个按钮点击了:
整体代码:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//事件监听
public class ActionListener {
public static void main(String[] args) {
Frame frame = new Frame();
Button button1 = new Button("btn1");
Button button2 = new Button("btn2");
MyActionListener myActionListener = new MyActionListener();
button1.addActionListener(myActionListener);
button2.addActionListener(myActionListener);
//使用了封装的监听窗口关闭的方法
WidowClos(frame);
frame.setLayout(new GridLayout(2,1));
frame.add(button1);
frame.add(button2);
frame.setSize(500, 500);
frame.setVisible(true);
}
public static void WidowClos(Frame frame) {
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口关闭了");
System.exit(0);
}
});
}
}
class MyActionListener implements java.awt.event.ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//获取是哪个按钮发生的点击事件
System.out.println(e.getActionCommand());
System.out.println("按钮监听事件");
}
}
也可以自定义按钮的信息(否则就会使用默认的信息):
button1.setActionCommand(“我是按钮1”);
文本框监听
先看看效果:
上源码(为文本框添加的监听是点击回车键触发的):
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//文本输入框
public class TestText01 {
public static void main(String[] args) {
new MyFrame();
}
}
class MyFrame extends Frame {
public MyFrame() {
//文本框
TextField textField = new TextField();
//为文本框添加监听
//点击回车会触发文本框监听事件
MyActionListener2 myActionListener2 = new MyActionListener2();
textField.addActionListener(myActionListener2);
add(textField);
setSize(500, 500);
setVisible(true);
}
}
class MyActionListener2 implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//getSource表示获取资源。这里资源指文本框内的数据
//getSource的返回类型为Object,为最高类,可以转为所有类型,这里我们转为文本框类型
TextField text1= (TextField) e.getSource();
//输出文本数据
System.out.println(text1.getText());
}
}
还可以隐藏用户的输入信息:
//设置替换编码
textField.setEchoChar('*');
效果:
设置点击回车获取文本数据后清空输入框:
代码:
text1.setText("");
–
搞一个简易的计算器
由于太简单就直接放上效果图和源码:
效果图:
源码:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestCalc {
public static void main(String[] args) {
new CalcFrame();
}
}
class CalcFrame extends Frame {
public CalcFrame() {
super("简易计算器");
//三个文本框
TextField textField01 = new TextField(10);
TextField textField02 = new TextField(10);
TextField textField03 = new TextField(30);
Button button = new Button("=");
button.addActionListener(new CalcLinister(textField01, textField02, textField03));
Label label = new Label("+");
setLayout(new FlowLayout());
add(textField01);
add(label);
add(textField02);
add(button);
add(textField03);
pack();
setVisible(true);
}
}
class CalcLinister implements ActionListener {
TextField num1, num2, num3;
public CalcLinister(TextField num1, TextField num2, TextField num3) {
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
}
@Override
public void actionPerformed(ActionEvent e) {
//获得加数和被加数
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
//计算,并将结果放到第三个文本框中
num3.setText(""+(n1+n2));
//清空前两个文本框
num1.setText("");
num2.setText("");
}
}
代码进阶版,使用面向对象实现:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestCalc {
public static void main(String[] args) {
new CalcFrame().LoadFrame();
}
}
class CalcFrame extends Frame {
TextField textField01, textField02, textField03;
public void LoadFrame() {
setTitle("简易计算器");
//三个文本框
textField01 = new TextField(10);
textField02 = new TextField(10);
textField03 = new TextField(20);
Button button = new Button("=");
button.addActionListener(new CalcLinister(this));
Label label = new Label("+");
setLayout(new FlowLayout());
add(textField01);
add(label);
add(textField02);
add(button);
add(textField03);
pack();
setVisible(true);
}
}
class CalcLinister implements ActionListener {
CalcFrame calcFrame;
public CalcLinister(CalcFrame calcFrame) {
this.calcFrame = calcFrame;
}
@Override
public void actionPerformed(ActionEvent e) {
//获得加数和被加数
int n1= Integer.parseInt(calcFrame.textField01.getText());
int n2= Integer.parseInt(calcFrame.textField02.getText());
//计算,并将结果放到第三个文本框中
calcFrame.textField03.setText("" + (n1 + n2));
//清空前两个文本框
calcFrame.textField01.setText("");
calcFrame.textField02.setText("");
}
}
使用内部类和面向对象实现:
内部类最大的好处就是能畅通无阻的访问自己外部类的方法和变量
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestCalc {
public static void main(String[] args) {
new CalcFrame().LoadFrame();
}
}
class CalcFrame extends Frame {
TextField textField01, textField02, textField03;
public void LoadFrame() {
setTitle("简易计算器");
//三个文本框
textField01 = new TextField(10);
textField02 = new TextField(10);
textField03 = new TextField(20);
Button button = new Button("=");
button.addActionListener(new CalcLinister());
Label label = new Label("+");
setLayout(new FlowLayout());
add(textField01);
add(label);
add(textField02);
add(button);
add(textField03);
pack();
setVisible(true);
}
private class CalcLinister implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
//获得加数和被加数
int n1 = Integer.parseInt(textField01.getText());
int n2 = Integer.parseInt(textField02.getText());
//计算,并将结果放到第三个文本框中
textField03.setText("" + (n1 + n2));
//清空前两个文本框
textField01.setText("");
textField02.setText("");
}
}
}
6. 画笔
Paint
画笔,字面意思就是像画笔一样,可以画一些图像或者文字,使用方法:
在idea中,先alt + ins
然后找到Paint:
–
用画笔画一个圆:
import java.awt.*;
public class TestPaint {
public static void main(String[] args) {
new MyPAint().loca();
}
}
class MyPAint extends Frame {
public void loca() {
setTitle("画笔");
setBounds(200, 200, 600, 500);
setVisible(true);
}
@Override
public void paint(Graphics g) {
//设置画笔颜色
g.setColor(Color.red);
//设置画笔要画的图形,并传递指定参数
g.drawOval(100,100,100,100);
//实心圆
g.fillOval(300,300,100,100);
}
}
效果图:
画笔使用完后,要把它恢复成最初的颜色,防止影响到下一次的绘画
就是将设置画笔颜色的代码注释或者删除掉再运行一次。
7. 鼠标监听
通过实现一个案例来了解鼠标监听,实现鼠标点击画到界面上一个点:
先看看效果图:
实现思想:
鼠标点击事件,每次点击将点击的横纵坐标(X、Y)的信息存放到动态数组ArrayList中,画笔根据动态数组中存放的横纵坐标信息在界面上画出点,每次都使用repaint(); 重画。
源码:
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouse {
public static void main(String[] args) {
new MyFrame().loca("画圆");
}
}
class MyFrame extends Frame {
ArrayList point;
public void loca(String name) {
setTitle(name);
setSize(500, 500);
//存放鼠标点击点的坐标
point = new ArrayList<>();
//在窗口中添加鼠标监听事件
addMouseListener(new MyMouseLiniser());
setVisible(true);
}
//画笔
@Override
public void paint(Graphics g) {
//使用迭代器,迭代ArrayList中的信息
Iterator iterator = point.iterator();
//使用while判断迭代后还有没有数据
while (iterator.hasNext()) {
//指针向下一位移动
Point point = (Point) iterator.next();
//设置画的点的信息
g.setColor(Color.BLACK);
g.fillOval(point.x, point.y, 10, 10);
}
}
//写一个方法将生成的点添加到存放点信息的ArrayList动态数组中
public void addPoint(Point points) {
point.add(points);
}
private class MyMouseLiniser extends MouseAdapter {
//鼠标点击事件
@Override
public void mousePressed(MouseEvent e) {
MyFrame myFrame = (MyFrame) e.getSource();
System.out.println(e.getX() + "," + e.getX());
//将信息传递到添加点到窗口上的方法
myFrame.addPoint(new Point(e.getX(), e.getY()));
//每点一次鼠标书信一次界面
myFrame.repaint();
}
}
}
8. 窗口监听
案例1,通过按钮隐藏窗口 (不是停止程序,只是隐藏):
思路:使用 setVisible( ); 进行控制
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//通过按钮隐藏窗口
public class TestWindow {
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
myFrame.local("按钮隐藏窗口");
}
}
class MyFrame extends Frame {
public void local(String name) {
Button button = new Button("close");
add(button, BorderLayout.CENTER);
button.addActionListener(new MyButtonLiniser());
addWindowListener(new MyWindowLiniser());
setTitle(name);
setSize(500, 500);
setVisible(true);
}
class MyButtonLiniser implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("隐藏窗口");
setVisible(false);
}
}
}
class MyWindowLiniser extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口正在关闭");
System.exit(0);
}
}
代码进阶,使用匿名内部类:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
//通过按钮隐藏窗口
public class TestWindow {
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
myFrame.local("按钮隐藏窗口");
}
}
class MyFrame extends Frame {
public void local(String name) {
Button button = new Button("close");
add(button, BorderLayout.CENTER);
//按钮监听器使用匿名内部类
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("隐藏窗口");
setVisible(false);
}
});
addWindowListener(new MyWindowLiniser());
setTitle(name);
setSize(500, 500);
setVisible(true);
}
}
class MyWindowLiniser extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口正在关闭");
System.exit(0);
}
}
–
玩一下窗口的各种监听,再实现个小功能(根据窗口状态鼎泰改变窗口标题):
先来看看效果:
1.当窗口打开时,显示“我开了”:
2.当窗口失去焦点,显示“人呢?”:
3.当窗口重新获得焦点显示“欢迎回来”:
代码(是在上面的小Demo基础上写的,所以有一些不太关键的代码,不过没影响):
import java.awt.*;
import java.awt.event.*;
//通过按钮隐藏窗口
public class TestWindow {
public static void main(String[] args) {
MyFrame myFrame = new MyFrame();
myFrame.local("按钮隐藏窗口");
}
}
class MyFrame extends Frame {
public void local(String name) {
Button button = new Button("close");
add(button, BorderLayout.CENTER);
//按钮监听器使用匿名内部类
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("隐藏窗口");
setVisible(false);
}
});
addWindowListener(new MyWindowLiniser());
setTitle(name);
setSize(500, 500);
setVisible(true);
}
}
class MyWindowLiniser implements WindowListener {
@Override
public void windowOpened(WindowEvent e) {
MyFrame myFrame= (MyFrame) e.getSource();
myFrame.setTitle("我开了");
System.out.println("窗口打开了");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("窗口正在关闭");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("窗口已经关闭");
}
@Override
public void windowIconified(WindowEvent e) {
//监听图标的这里我们先不管他
}
@Override
public void windowDeiconified(WindowEvent e) {
//监听图标的这里我们先不管他
}
@Override
public void windowActivated(WindowEvent e) {
MyFrame myFrame= (MyFrame) e.getSource();
myFrame.setTitle("欢迎回来");
System.out.println("窗口已被激活");
}
@Override
public void windowDeactivated(WindowEvent e) {
MyFrame myFrame= (MyFrame) e.getSource();
myFrame.setTitle("人呢?");
System.out.println("窗口失去焦点");
}
}
9. 键盘监听
键盘每一个按键对应了一个值,java把他们定义成了常量。
由于太多了就截取了一部分:
搞一个小demo:
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
//键盘监听
public class TestKeyListener {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame {
public KeyFrame() {
super("键盘监听");
setBounds(100, 100, 500, 500);
setVisible(true);
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//获取点击的按键对应的值
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_E) {
System.out.println("你点击了“E”键");
}
}
});
}
}
–
10. Swing
和AWT比较,AWT是基础,Swing是封装,Swing的界面更加美观
代码:
import javax.swing.*;
//使用Swing搭建窗口
public class TestJFrame01 {
//用于初始化的方法
public void init() {
JFrame frame = new JFrame("Swing窗口");
frame.setVisible(true);
frame.setBounds(100, 100, 500, 500);
//Swing自带的窗口关闭方法
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestJFrame01().init();
}
}
与AWT相比,Swing有自带的窗口关闭方法,分别有几种不同的关闭方式:
setDefaultCloseOperation
用户单击窗口关闭按钮时执行的操作
- 参数
- DO_NOTHING_ON_CLOSE (0)
不执行任何操作;要求程序在已注册的 WindowListener 对象的 windowClosing 方法中处理该操作。
即用户单击窗口关闭按钮时无法关闭这个窗口
- HIDE_ON_CLOSE (1)
调用任意已注册的 WindowListener 对象后自动隐藏该窗体。
此时程序没有关闭,只是隐藏了该窗口
- DISPOSE_ON_CLOSE (2)
调用任意已注册 WindowListener 的对象后自动隐藏并释放该窗体。
此时程序没有关闭。只是隐藏并释放该窗口的资源
- EXIT_ON_CLOSE (3)
使用 System exit 方法退出应用程序。仅在应用程序中使用。
此时关闭程序以及窗口
默认情况下,该值被设置为 HIDE_ON_CLOSE。
即没有设置该函数时,相当于
f.setDefaultCloseOperation(f. HIDE_ON_CLOSE);
或者f.setDefaultCloseOperation(1);
–
设置窗口颜色
我们先试试用AWT的方法设置窗口颜色
import javax.swing.*;
import java.awt.*;
//使用Swing搭建窗口
public class TestJFrame01 {
//用于初始化的方法
public void init() {
JFrame frame = new JFrame("Swing窗口");
frame.setVisible(true);
frame.setBounds(100, 100, 500, 500);
JLabel label = new JLabel("来学java啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊");
//设置颜色
frame.setBackground(Color.BLACK);
frame.add(label);
//Swing自带的窗口关闭方法
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestJFrame01().init();
}
发现没效果,诶,肿么回事。
这时候就要引入Swing独有的一个对象了:容器
容器:上一步设置的颜色实际上是显式在容器中的,所以要显示颜色就要显示出容器。
代码:
import javax.swing.*;
import java.awt.*;
public class ContainerDemo01 {
public static void main(String[] args) {
new MyContainer().init();
}
}
class MyContainer extends JFrame {
public void init() {
this.setTitle("容器");
//获得一个容器
Container container = this.getContentPane();
container.setBackground(Color.yellow);
JLabel label = new JLabel("啦啦啦啦啦啦");
//文本标签居中
label.setHorizontalAlignment(SwingConstants.CENTER);
this.add(label);
this.setVisible(true);
this.setBounds(100, 100, 500, 500);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
效果:
Swing自带了个文本标签居中的方法(真是方便):
lsetHorizontalAlignment();
11. 弹窗
JDialog,本质上就是个窗口:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class JDialogDemo extends JFrame {
public JDialogDemo() {
this.setTitle("弹窗");
this.setVisible(true);
this.setBounds(100, 100, 500, 500);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
//获取容器
Container contentPane = this.getContentPane();
//空布局(绝对布局)
contentPane.setLayout(null);
JButton button = new JButton("点击弹窗");
button.setBounds(50, 50, 100, 50);
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new MyDialog();
}
});
contentPane.add(button);
}
public static void main(String[] args) {
new JDialogDemo();
}
}
//弹窗窗口
class MyDialog extends JDialog {
public MyDialog() {
this.setVisible(true);
this.setBounds(100, 100, 100, 200);
Container contentPane = this.getContentPane();
contentPane.add(new JLabel("牛蛙牛啊牛蛙牛啊"));
contentPane.setLayout(null);
}
}
新知识:空布局(绝对布局) contentPane.setLayout(null); ,就是没有布局,通过相对坐标来通知组件在窗口中的位置。
注意:在JDialog 生成的弹窗中,默认含有Swing的窗口关闭方法,所以可以省略下面的这一句代码,写上的话会报错:
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JOptionPane
这个是封装好的弹窗,使用比较方便也比较美观:
showMessageDialog只有一个确定按钮;
1.提示框
JOptionPane.showMessageDialog(null, “普通提示框!”, “哈哈”,JOptionPane.INFORMATION_MESSAGE);
2.警告框
JOptionPane.showMessageDialog(null, “警告提示框!”, “哈哈”,JOptionPane.WARNING_MESSAGE);
3.错误框
JOptionPane.showMessageDialog(null, “错误提示框!”, “哈哈”,JOptionPane.ERROR_MESSAGE);
–
showOptionDialog有两个选择按钮,有返回值是int型,0或者1,0代表是,1代表否
1.含有是否按钮
JOptionPane.showConfirmDialog(null,“是 或 否”,“标题”,JOptionPane.YES_NO_OPTION);
如何获取到选了哪个选项呢?
选项后,会返回一个int型的数据,对应选项如下:
int a = JOptionPane.showConfirmDialog(null, "是 或 否", "标题", JOptionPane.YES_NO_OPTION);
if (a == JOptionPane.YES_OPTION) {
System.out.println("点击了 是");
}
if (a == JOptionPane.NO_OPTION) {
System.out.println("点击了 否");
}
2.自定义按钮
Object[] options = {就这?", “怎样?”, "不过如此};
JOptionPane.showOptionDialog(null, “你说话呀!!”, “标题”, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
获取返回值:
Object[] options = {"就这?", "怎样?", "不过如此"};
int a = JOptionPane.showOptionDialog(null, "你说话呀!!", "标题", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
System.out.println(a);
返回值同样是个int型的数据,对应的是选项数组中选项对应的下标。
注意:选项不要有相同的,如果有相同的,那么只会获取到第一个的下标。
–
showInputDialog有输入列表,并且可以将你选择的那个对象返回;
1. 有下拉条的提示框
Object[] objects = {“我”, “是”, “谁”};
JOptionPane.showInputDialog(null, “请选择你的身份”, “身份”, JOptionPane.PLAIN_MESSAGE, new ImageIcon(“icon.png”), objects, “足球”);
Object[] objects = {"我", "是", "谁"};
String s = (String) JOptionPane.showInputDialog(null, "请选择你的身份", "身份", JOptionPane.PLAIN_MESSAGE, new ImageIcon("icon.png"), objects, "足球");
System.out.println(s);
2. 带输入框的提示框
JOptionPane.showInputDialog(null, “请输入:\n”, “title”, JOptionPane.PLAIN_MESSAGE);
获取值:
String title = JOptionPane.showInputDialog(null, "请输入:\n", "title", JOptionPane.PLAIN_MESSAGE);
System.out.println(title);
12. Icon图标
关键字:Icon(继承这个接口)
重写三个方法
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
}
@Override
public int getIconWidth() {
return 0;
}
@Override
public int getIconHeight() {
return 0;
}
分别是画图标,获取宽和高。
代码:
import javax.swing.*;
import java.awt.*;
public class Test01 extends JFrame implements Icon {
private int width;
private int height;
public Test01() {
}
public Test01(int width, int height) {
this.width = width;
this.height = height;
}
public static void main(String[] args) {
new Test01().init();
}
public void init() {
Test01 icon = new Test01(15, 15);
JLabel label = new JLabel("图标测试", icon, SwingConstants.CENTER);
Container contentPane = getContentPane();
contentPane.add(label);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(500, 500);
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
//这个是画图标的方法,这里我们先画一个实心的○
g.fillOval(x, y, width, height);
}
@Override
public int getIconWidth() {
return this.width;
}
@Override
public int getIconHeight() {
return this.height;
}
}
–
图片图标:
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class ImgIconDemo extends JFrame {
public ImgIconDemo() {
//获取图片路径
JLabel label = new JLabel("图片图标");
URL url = ImgIconDemo.class.getResource("TX.jpg");
ImageIcon imageIcon = new ImageIcon(url);
label.setIcon(imageIcon);
label.setHorizontalAlignment(SwingConstants.CENTER);
Container contentPane = getContentPane();
contentPane.add(label);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(500, 500);
}
public static void main(String[] args) {
new ImgIconDemo();
}
}
图片要与项目代码放在同一级文件夹下:
效果:
13.JPanel
在一个窗口中添加不同的JPanel面板,每个JPanel使用不同的布局。
效果:
代码:
import javax.swing.*;
import java.awt.*;
public class JPanelDemo extends JFrame {
public JPanelDemo() {
Container contentPane = getContentPane();
contentPane.setLayout(new GridLayout(2, 2, 10, 10));//设置主布局是表格布局,2行2列,边距10px
JPanel panel1 = new JPanel(new GridLayout(1, 2));
JPanel panel2 = new JPanel(new GridLayout(3, 2));
JPanel panel3 = new JPanel(new GridLayout(2, 1));
JPanel panel4 = new JPanel(new GridLayout(2, 2));
panel1.add(new JButton("1"));
panel1.add(new JButton("1"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel2.add(new JButton("2"));
panel3.add(new JButton("3"));
panel3.add(new JButton("3"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
panel4.add(new JButton("4"));
contentPane.add(panel1);
contentPane.add(panel2);
contentPane.add(panel3);
contentPane.add(panel4);
setSize(500, 500);
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JPanelDemo();
}
}
14.滚动条面板 JScrollPanel
效果:
代码:
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo() {
Container contentPane = getContentPane();
TextArea textArea = new TextArea(20, 50);
textArea.setText("牛牛牛");
//滚动条面板
JScrollPane jScrollPane = new JScrollPane(textArea);
contentPane.add(jScrollPane);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
14. 图片按钮
效果:
代码:
import javax.swing.*;
import java.awt.*;
import java.net.URL;
public class IconButtonDemo extends JFrame {
//图片按钮,就是在按钮上加个图片
public IconButtonDemo() {
Container contentPane = getContentPane();
URL resource = IconButtonDemo.class.getResource("TX.jpg");//自动获取图片的路径
System.out.println(resource);
Icon icon = new ImageIcon(resource);//将图片处理为Icon图标
JButton button = new JButton();
button.setIcon(icon);//将图标放入按钮
button.setToolTipText("这是个图片按钮");//鼠标悬浮在按钮上显示的文字
contentPane.add(button);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new IconButtonDemo();
}
}
15.单选框(JRadioButton)
效果:
代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//单选框
public class JRadioButtonDemo01 extends JFrame {
public JRadioButtonDemo01() {
Container contentPane = getContentPane();
JRadioButton jRadioButton01 = new JRadioButton("JRadioButton01");
//通过点击事件获取单选框的值
jRadioButton01.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(jRadioButton01.getText());
}
});
JRadioButton jRadioButton02 = new JRadioButton("JRadioButton02");
jRadioButton02.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(jRadioButton02.getText());
}
});
JRadioButton jRadioButton03 = new JRadioButton("JRadioButton03");
jRadioButton03.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(jRadioButton03.getText());
}
});
ButtonGroup buttonGroup = new ButtonGroup();//将单选框添加到同一个组
buttonGroup.add(jRadioButton01);
buttonGroup.add(jRadioButton02);
buttonGroup.add(jRadioButton03);
contentPane.add(jRadioButton01,BorderLayout.SOUTH);
contentPane.add(jRadioButton02,BorderLayout.CENTER);
contentPane.add(jRadioButton03,BorderLayout.NORTH);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JRadioButtonDemo01();
}
}
16.多选框(JCheckBox)
效果:
代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//单选框
public class JCheckBoxDemo01 extends JFrame {
public JCheckBoxDemo01() {
Container contentPane = getContentPane();
JCheckBox jCheckBox01 = new JCheckBox("jCheckBox01");
JCheckBox jCheckBox02 = new JCheckBox("jCheckBox02");
JCheckBox jCheckBox03 = new JCheckBox("jCheckBox03");
contentPane.add(jCheckBox01,BorderLayout.NORTH);
contentPane.add(jCheckBox02,BorderLayout.CENTER);
contentPane.add(jCheckBox03,BorderLayout.SOUTH);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JCheckBoxDemo01();
}
}
17.列表框(JComboBox)
效果:
代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class JComboBoxDemo01 extends JFrame {
public JComboBoxDemo01() {
Container contentPane = getContentPane();
JComboBox box = new JComboBox();
box.addItem("a");
box.addItem("b");
box.addItem("c");
box.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println(box.getSelectedItem());
}
});
contentPane.add(box);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JComboBoxDemo01();
}
}
18.列表框(JList)
效果:(实现了动态添加列表数据)
代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Vector;
public class JListDemo01 extends JFrame {
public JListDemo01() {
Container contentPane = getContentPane();
JScrollPane jScrollPane = new JScrollPane();
//静态放入数据
//String[] list = {"1", "2", "3"};
//动态放入数据
DefaultListModel dm = new DefaultListModel();
JList Jlist = new JList(dm);
Button add = new Button("add");
add.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("好");
dm.addElement("好");
}
});
contentPane.add(Jlist, BorderLayout.NORTH);
contentPane.add(add, BorderLayout.SOUTH);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JListDemo01();
}
}
19. 文本框(JTextField),密码框(JPasswordField),文本域(JTextArea)
文本框:
代码:
import javax.swing.*;
import java.awt.*;
public class TestTextDemo extends JFrame {
public TestTextDemo() {
Container contentPane = getContentPane();
JTextField jTextField = new JTextField("文本框",5);//占5行
contentPane.add(jTextField,BorderLayout.CENTER);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo();
}
}
密码框:
代码:
import javax.swing.*;
import java.awt.*;
public class TestTextDemo extends JFrame {
public TestTextDemo() {
Container contentPane = getContentPane();
JPasswordField jPasswordField = new JPasswordField();//密码框
jPasswordField.setEchoChar('*');//设置密码框显示格式
contentPane.add(jPasswordField,BorderLayout.CENTER);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new TestTextDemo();
}
}
文本框:(与滚动条面板搭配使用)
代码:
import javax.swing.*;
import java.awt.*;
public class JScrollDemo extends JFrame {
public JScrollDemo() {
Container contentPane = getContentPane();
TextArea textArea = new TextArea(20, 50);
textArea.setText("牛牛牛");
//滚动条面板
JScrollPane jScrollPane = new JScrollPane(textArea);
contentPane.add(jScrollPane);
setVisible(true);
setSize(500, 500);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
new JScrollDemo();
}
}
完