GUI编程-AWT
AWT(Abstract Window Tool)
0.GUI(Graphic User Interface)
- GUI(Graphic User Interface)核心技术:Swing、AWT(Abstract Window Tool);
- 缺点:界面不美观,需要jre环境;
- 要学:了解MVC架构,了解监听;
可以写出自己想要的小工具;
有些老软件可能还有Swing界面;
AWT包含了很多类和接口,在java.awt下,比如窗口、按钮、文本框等元素:
1.Frame窗体
/**
* Frame:常用方法
*/
public class D01Frame {
public static void main(String[] args) {
//创建窗口
Frame frame=new Frame();
//设置标题
frame.setTitle("AWT Frame");
//设置窗口大小
frame.setSize(400,300);
//设置背景颜色
frame.setBackground(Color.BLUE);
//设置初始位置
frame.setLocation(100,100);
//设置不可变大小
frame.setResizable(false);
//设置可行性
frame.setVisible(true);
}
}
2.Panel面板
- 面板不能单独存在,必须嵌入窗体;
- 可看成是一个空间,不能单独存在,需装入到窗体中;
- 组件尽量放在面板上;
/**
* Panel
* 可看成是一个空间,但不能单独存在
* 监听:适配器模式,窗口关闭
*/
public class D02Panel {
public static void main(String[] args) {
Frame frame = new Frame("AWT Panel");
//布局的概念
Panel panel = new Panel();
//设置布局
frame.setLayout(null);
frame.setBounds(100,100,500,300);
frame.setBackground(Color.DARK_GRAY);
//panel设置坐标,相对于frame
panel.setBounds(50,50,400,200);
panel.setBackground(Color.cyan);
//装入面板
frame.add(panel);
frame.setVisible(true);
//监听事件:关闭窗口,适配器模式
frame.addWindowListener(new WindowAdapter() {
//关闭窗口事件
@Override
public void windowClosing(WindowEvent e) {
//结束程序
System.exit(0);
}
});
}
}
3.布局管理器
3.1 流式布局
使用FlowLayout布局方式的容器中组件按照加入的先后顺序按照设置的对齐方式(居中、左对齐、右对齐)从左向右排列,一行排满(即组件超过容器宽度后)到下一行开始继续排列。
特点
- 组件按照设置的对齐方式进行排列;
- 不管对齐方式如何,组件均按照从左到右的方式进行排列,一行排满,转到下一行。(比如按照右对齐排列,第一个组件在第一行最右边,添加第二个组件时,第一个组件向左平移,第二个组件变成该行最右边的组件,这就是从左向右方式进行排列);
- 是一个基本的布局管理器,可以在许多布局环境下方便地使用;
- FlowLayout不实现LayoutManager2接口,不需要对它布局的组件设置约束条件;
**构造方法**
FlowLayout() //构造一个新的 FlowLayout,默认居中对齐,默认的水平和垂直间隙是 5 个单位。;
FlowLayout(int align) //构造一个新的 FlowLayout,具有指定的对齐方式,默认的水平和垂直间隙是 5 个单位;
FlowLayout(int align,int hgap,int vgap) //创建一个新的流布局管理器,它具有指定的对齐方式以及指定的水平和垂直间隙;
**字段**
static int LEFT/0 //每行组件左对齐
static int CENTER/1 //每行组件居中对齐
static int RIGHT/2 //每行组件右对齐
static int LEADING/3 //每行组件对齐到容器开始边,例如,从左到右的方向向左;
static int TRAILING/4 //每行组件对齐到容器结束边,例如,从左到右的方向向右;
【注意】0,1,2,3,4以外的值,则为左对齐;
**方法**
Void setAlignment(int align) //设置此布局的对齐方式;
void setHgap(int hgap) //设置组件之间以及组件与 Container 的边之间的水平间隙;
void setVgap(int vgap) //设置组件之间以及组件与 Container 的边之间的垂直间隙;
3.2 方位布局(中间位置默认保留)
这是一个布置容器的边框布局,它可以对容器组件进行安排,并调整其大小,使其符合下列五个区域:北、南、东、西、中。每个区域最多只能包含一个组件,并通过相应的常量进行标识:NORTH、SOUTH、EAST、WEST、CENTER。
特点
- 可以把组件放在这五个位置的任意一个,如果未指定位置,则缺省的位置是CENTER;
- 南、北位置控件各占据一行,控件宽度将自动布满整行。东、西和中间位置占据一行;
- 若东、西、南、北位置无控件,则中间控件将自动布满整个屏幕;
- 若东、西、南、北位置中无论哪个位置没有控件,则中间位置控件将自动占据没有控件的位置;
- 它是窗口、框架的内容窗格和对话框等的缺省布局。
**构造方法**
BorderLayout() //构造一个组件之间没有间距(默认间距为0像素)的新边框布局;
BorderLayout(int hgap, int vgap) //构造一个具有指定组件(hgap为横向间距,vgap为纵向间距)间距的边框布局;
**字段**
static int LEFT/0 //每行组件左对齐
static int CENTER/1 //每行组件居中对齐
static int RIGHT/2 //每行组件右对齐
static int LEADING/3 //每行组件对齐到容器开始边,例如,从左到右的方向向左;
static int TRAILING/4 //每行组件对齐到容器结束边,例如,从左到右的方向向右;
【注意】0,1,2,3,4以外的值,则为左对齐;
**方法**
void setHgap(int hgap) //设置组件之间的水平间距;
void setVgap(int vgap) //设置组件之间的垂直间距;
int getHgap() //返回组件之间的水平间距;
int getVgap() //返回组件之间的垂直间距;
void removeLayoutComponent(Component comp) //从此边框布局中移除指定组件;
3.3 网格布局
使容器中的各组件呈M行×N列的网格状分布;
特点
- 网格每列宽度相同,等于容器的宽度除以网格的列数;
- 网格每行高度相同,等于容器的高度除以网格的行数;
- 各组件的排列方式为:从上到下,从左到右;
- 组件放入容器的次序决定了它在容器中的位置;
- 容器大小改变时,组件的相对位置不变,大小会改变;
- 设置网格布局行数和列数时,行数或者列数可以有一个为零。若rows为0,cols为3,则列数固定为3,行数不限,每行只能放3个控件或容器。若cols为0,rows为3,则行数固定为3,列数不限,且每行必定有控件,若组件个数不能整除行数,则除去最后一行外的所有行组件个数为:Math.ceil(组件个数/rows);
Math.ceil(double x)
:传回不小于x的最小整数值。比如行数为3,组件数为13个,则Math.ceil(13/3)=5,即第一行,第二行组件数各为5个,剩下的组件放在最后一行。 - 若组件数超过网格设定的个数,则布局管理器会自动增加网格个数,原则是保持行数不变。
**构造方法**
GridLayout() //创建具有默认值的网格布局,即每个组件占据一行一列;
GridLayout(int rows, int cols) //创建具有指定行数和列数的网格布局。Rows为行数,cols为列数;
GridLayout(int rows, int cols, int hgap, int vgap) //创建具有指定行数、列数以及组件水平、纵向一定间距的网格布局;
**方法**
void setColumns(int cols) //将此布局中的列数设置为指定值;
void setHgap(int hgap) //将组件之间的水平间距设置为指定值;
void setRows(int rows) //将此布局中的行数设置为指定值;
void setVgap(int vgap) //将组件之间的垂直间距设置为指定值;
int getColumns() //获取此布局中的列数;
int getHgap() //获取组件之间的水平间距;
int getRows() //获取此布局中的行数;
int getVgap() //获取组件之间的垂直间距;
void removeLayoutComponent(Component comp) //从布局移除指定组件;
String toString() //返回此网格布局的值的字符串表示形式;
3.4 卡片布局
卡片布局能够让多个组件共享同一个显示空间,共享空间的组件之间的关系就像一叠牌,组件叠在一起,初始时显示该空间中第一个添加的组件,通过CardLayout类提供的方法可以切换该空间中显示的组件;
**构造方法**
CardLayout() //创建一个大小为零的新卡片布局;
CardLayout(int hgap, int vgap) //创建具有指定水平和垂直间隙的新卡片布局;
**方法**
void first(Container) //显示第一个添加到容器中的构件;
void last(Container) //显示最后一个添加到容器中的构件;
void next(Container) //显示当前构件后加入到容器中的构件。如果当前是最后一个构件,那么显示第一个构件;
void previous(Container) //显示在当前显示构件前加入到容器中的构件。如果当前构件是第一个,那么显示最后一个构件;
void show(Container,String) //显示名称和传递的字符串相匹配的构件。如果没有构件匹配,则为空操作;
3.5 网格组布局
GridBagLayout
类是一个灵活的布局管理器,GridBagLayout类的对象维持一个动态的矩形单元网格,然后我们可以把组件放进一个或多个矩形单元网格,组件大就多放几个,组件小就少放几个。而每个组件,要占几个网格单元,每个组件要占领的位置在哪等等,都是要用GridBagConstraints
类的对象来设置。
**GridBagLayout构造方法**
GridBagLayout() //创建网格包布局管理器;
**GridBagLayout方法**
void setConstraints(Component comp, GridBagConstraints constraints) //设置此布局中指定组件的约束条件;
`java.awt.GridBagConstraints`:用于指定使用 GridBagLayout 类布置的组件的约束;
**GridBagConstraints构造方法**
GridBagConstraints() //创建一个 GridBagConstraint 对象,将其所有字段都设置为默认值;
GridBagConstraints(int gridx, int gridy, int gridwidth, int gridheight, double weightx, double weighty, int anchor, int fill, Insets insets, int ipadx, int ipady) //创建一个 GridBagConstraints 对象,将其所有字段都设置为传入参数;
* gridx:指定包含组件的显示区域开始边的单元格[默认值为 RELATIVE,应为非负值],其中行的第一个单元格为 gridx=0,组件显示区域的开始边指的是水平的、从左到右的容器的左边缘,以及水平的、从右到左的容器的右边缘。值 RELATIVE 指定将组件放置在添加此组件之前刚刚添加到容器中的组件的后面;
* gridy:指定位于组件显示区域的顶部的单元格[默认值为 RELATIVE,应为非负值],其中最上边的单元格为 gridy=0,值 RELATIVE 指定将组件放置在添加此组件之前刚刚添加到容器中的组件的下面;
* gridwidth:指定组件显示区域的某一行中的单元格数[默认值为 1, 应为非负值],使用 REMAINDER 指定组件的显示区域,该区域的范围是从 gridx 到该行的最后一个单元格;使用 RELATIVE 指定组件的显示区域,该区域的范围是从 gridx 到它所在行的倒数第二个单元格;
* gridheight:指定在组件显示区域的一列中的单元格数[默认值为 1, 应为非负值],使用 REMAINDER 指定组件的显示区域,该区域的范围是从 gridy 到该列的最后一个单元格;使用 RELATIVE 指定组件的显示区域,该区域的范围是从 gridy 到它所在列的倒数第二个单元格;
* weightx:指定如何分布额外的水平空间[默认值为 0,应为非负值],网格包布局管理器计算出列的权重将是列的所有组件中最大的 weightx,如果得到的布局在水平方向上比需要填充的区域小,那么系统会将额外的空间按照其权重比例分布到每一列,权重为零的列不会得到额外的空间;如果所有的权重都为零,则所有的额外空间都将出现在单元格的网格之间和左右边缘之间;
* weighty:指定如何分布额外的垂直空间[默认值为 0,应为非负值],网格包布局管理器计算出行的权重将是行的所有组件中最大的 weighty,如果得到的布局在垂直方向上比需要填充的区域小,则系统会将额外的空间按照其权重比例分布到每一行,权重为零的行不会得到额外的空间;如果所有的权重都为零,则所有的额外空间都将出现在单元格的网格之间和上下边缘之间;
* anchor:当组件小于其显示区域时使用此字段,它可以确定在显示区域中放置组件的位置[默认值为 CENTER],可能的值有三种:相对于方向的值、相对于基线的值和绝对值。相对于方向的值是相对于容器的组件方向属性进行解释的,相对于基线值是相对于基线进行解释的,绝对值则不然:
- 方向相对值有:PAGE_START、PAGE_END、LINE_START、LINE_END、FIRST_LINE_START、FIRST_LINE_END、LAST_LINE_START 和 LAST_LINE_END;
- 相对于基线的值有:BASELINE、BASELINE_LEADING、BASELINE_TRAILING、ABOVE_BASELINE、ABOVE_BASELINE_LEADING、ABOVE_BASELINE_TRAILING、BELOW_BASELINE、BELOW_BASELINE_LEADING 和 BELOW_BASELINE_TRAILING;
- 绝对值有:CENTER、NORTH、NORTHEAST、EAST、SOUTHEAST、SOUTH、SOUTHWEST、WEST 和 NORTHWEST;
* fill:当组件的显示区域大于它所请求的显示区域的大小时使用此字段,它可以确定是否调整组件大小,以及在需要的时候如何进行调整[默认值为 NONE],以下值适用于 fill:
- NONE:不调整组件大小;
- HORIZONTAL:加宽组件,使它在水平方向上填满其显示区域,但是不改变高度;
- VERTICAL:加高组件,使它在垂直方向上填满其显示区域,但是不改变宽度;
- BOTH:使组件完全填满其显示区域;
* insets:此字段指定组件的外部填充,即组件与其显示区域边缘之间间距的最小量[默认值为 new Insets(0, 0, 0, 0);],按顺序分别代表上top、左left、下bottom、右right四个方向空出的间距;当组件的fill=NONE时,指定insects值是无意义的;
* ipadx:此字段指定组件的内部填充,即给组件的最小宽度添加多大的空间,组件的宽度至少为其最小宽度加上 ipadx 像素[默认值为 0];
* ipady:此字段指定内部填充,即给组件的最小高度添加多大的空间,组件的高度至少为其最小高度加上 ipady 像素[默认值为 0];可以用ipadx,ipady的值来指定组件的大小,而不必指定组件的大小,否则会有意想不到的效果;
/**
* Layout 布局管理器
* FlowLayout,BorderLayout,GridLayout
*/
public class D03Layout {
public static void main(String[] args) {
Frame frame = new Frame("AWT Layout");
frame.setSize(300,200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
//组件-按钮
Button button1 = new Button("button1");
Button button2 = new Button("button2");
Button button3 = new Button("button3");
Button button4 = new Button("button4");
Button button5 = new Button("button5");
Button button6 = new Button("button6");
/*
//流式布局 Flowlayout
frame.setLayout(new FlowLayout());
frame.setLayout(new FlowLayout(FlowLayout.LEADING));
frame.setLayout(new FlowLayout(FlowLayout.TRAILING));
//添加按钮
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
*/
//方位布局 BorderLayout
frame.add(button1,BorderLayout.EAST);
frame.add(button2,BorderLayout.WEST);
frame.add(button3,BorderLayout.SOUTH);
frame.add(button4,BorderLayout.NORTH);
frame.add(button5,BorderLayout.CENTER);
frame.add(button5,BorderLayout.CENTER);
//表格布局 GridLayout
frame.setLayout(new GridLayout(3,2));
frame.add(button1);
frame.add(button2);
frame.add(button3);
frame.add(button4);
frame.add(button5);
frame.add(button6);
frame.pack(); //java函数,压缩布局
}
}
【练习】
/**
* Layout练习
*/
public class D04ExLayout {
public static void main(String[] args) {
//Frame
Frame frame=new Frame("布局练习");
frame.setBounds(200,200,500,400);
frame.setVisible(true);
frame.setLayout(new GridLayout(2,1));
//四个面板
Panel panelTop=new Panel(new BorderLayout());
Panel panelTopMidder = new Panel(new GridLayout(2, 1));
Panel panelBottom = new Panel(new BorderLayout());
Panel panelBottomCenter = new Panel(new GridLayout(2, 2));
//上部布局
panelTop.add(new Button("Top-East"), BorderLayout.EAST);
panelTop.add(new Button("Top-West"), BorderLayout.WEST);
panelTopMidder.add(new Button("Top-Mid-Up"));
panelTopMidder.add(new Button("Top-Mid-Down"));
panelTop.add(panelTopMidder, BorderLayout.CENTER);
//下部布局
panelBottom.add(new Button("Bot-West"), BorderLayout.WEST);
panelBottom.add(new Button("Bot-East"), BorderLayout.EAST);
//中间四个
for (int i = 0; i < 4; i++) {
panelBottomCenter.add(new Button("Center-" + i));
}
panelBottom.add(panelBottomCenter, BorderLayout.CENTER);
//添加到窗口
frame.add(panelTop);
frame.add(panelBottom);
//窗口关闭监听
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
}
4.事件监听
- 当某个事情发生时,干什么?
- 点击鼠标、键盘操作
/**
* 两个按钮,实现同一个监听
*/
public class D05ActionListen {
public static void main(String[] args) {
Frame frame = new Frame("事件监听");
frame.setLayout(new FlowLayout(FlowLayout.LEFT));
Button btnStart = new Button("start");
Button btnStop = new Button("stop");
frame.add(btnStart);
frame.add(btnStop);
frame.pack();
frame.setVisible(true);
//显示定义触发返回的命令,默认为label值
btnStop.setActionCommand("button-stop");
//添加监听
MyMonitor myMonitor=new MyMonitor();
btnStart.addActionListener(myMonitor);
btnStop.addActionListener(myMonitor);
}
}
//自定义监听器
class MyMonitor implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e.getActionCommand()+":被点击了");
if(e.getActionCommand().equals("start")){
System.out.println("click start= "+e.getActionCommand());
}
if (e.getActionCommand().equals("stop")){
System.out.println("click stop= "+e.getActionCommand());
}
}
}
5.输入框事件监听
/**
* TextField 文本框监听事件
*/
public class D06TextFieldListen {
public static void main(String[] args) {
//启动程序
new MainFrame();
}
}
class MainFrame extends Frame{
public MainFrame(){
TextField textField = new TextField();
add(textField);
setVisible(true);
pack();
//监听文本框输入的文字
TxtListener txtListener=new TxtListener();
//按下enter,就会触发这个输入框事件
textField.addActionListener(txtListener);
//设置替换编码,类似密码
textField.setEchoChar('*');
}
}
class TxtListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
TextField textField =(TextField)e.getSource();//获得资源,返回一个对象
System.out.println(textField.getText());//获得输入框中的文本
textField.setText("");//清空文本框
}
}
6.简易计算器
/**
* 简易计算器
* 组件、容器、布局、监听
*/
public class D07ExCalcutor {
public static void main(String[] args) {
new Calculator();
}
}
//计算器类
class Calculator extends Frame{
public Calculator(){
//3个文本框
TextField num1 = new TextField(10);
TextField num2 = new TextField(10);
TextField num3 = new TextField(20);
//1个标签
Label label = new Label("+");
//1个按钮
Button button = new Button("=");
button.addActionListener(new CalcListener(num1,num2,num3));
//布局
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setTitle("简易计算器");
setLocationRelativeTo(null); //建议增加这条语句,方便查看
setVisible(true);
}
}
//监听器类
class CalcListener implements ActionListener{
//获取3个变量
private TextField num1,num2,num3;
public CalcListener(TextField num1, TextField num2, TextField num3) {
this.num1 = num1;
this.num2 = num2;
this.num3 = num3;
}
@Override
public void actionPerformed(ActionEvent e) {
//1.获取加数、被加数
int num1 = Integer.parseInt(this.num1.getText());
int num2 = Integer.parseInt(this.num2.getText());
//2.加法运算后放到第三个文本框
this.num3.setText("" +(num1 + num2));
//3.清空前两个文本框
this.num1.setText("");
this.num2.setText("");
}
}
利用组合的思想改造,组合>继承
/**
* 简易计算器
* 组合的思想-改造
*/
public class D07ExCalcutor {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器类
class Calculator extends Frame{
//属性
TextField num1,num2,num3;
//方法
public void loadFrame(){
//组件:3个文本框,1个标签,1个按钮
num1 = new TextField(10);
num2 = new TextField(10);
num3 = new TextField(20);
Label label = new Label("+");
Button button = new Button("=");
button.addActionListener(new CalcListener(this));
//布局
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setTitle("简易计算器");
setLocationRelativeTo(null); //建议增加这条语句,方便查看
setVisible(true);
}
}
//监听器类
class CalcListener implements ActionListener{
//获取计算器这个对象,在一个类中组合另外一个类
Calculator calculator=null;
public CalcListener(Calculator calculator){
this.calculator=calculator;
}
@Override
public void actionPerformed(ActionEvent e) {
//1.获取加数、被加数
int num1 = Integer.parseInt(calculator.num1.getText());
int num2 = Integer.parseInt(calculator.num2.getText());
//2.加法运算后放到第三个文本框
calculator.num3.setText("" +(num1 + num2));
//3.清空前两个文本框
calculator.num1.setText("");
calculator.num2.setText("");
}
}
完全面向对象的思想-内部类
/**
* 简易计算器
* 完全面向对象的思想-内部类,更好的包装
*/
public class D07ExCalcutor {
public static void main(String[] args) {
new Calculator().loadFrame();
}
}
//计算器类
class Calculator extends Frame{
//属性
TextField num1,num2,num3;
//方法
public void loadFrame(){
//组件:3个文本框,1个标签,1个按钮
num1 = new TextField(10);
num2 = new TextField(10);
num3 = new TextField(20);
Label label = new Label("+");
Button button = new Button("=");
button.addActionListener(new CalcListener());
//布局
setLayout(new FlowLayout());
add(num1);
add(label);
add(num2);
add(button);
add(num3);
pack();
setTitle("简易计算器");
setLocationRelativeTo(null); //建议增加这条语句,方便查看
setVisible(true);
}
//监听器类
//内部类最大的好处:可直接访问外部类的属性和方法
private class CalcListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
//1.获取加数、被加数
int n1 = Integer.parseInt(num1.getText());
int n2 = Integer.parseInt(num2.getText());
//2.加法运算后放到第三个文本框
num3.setText("" +(n1 + n2));
//3.清空前两个文本框
num1.setText("");
num2.setText("");
}
}
}
7.画图(Graphics)
1.Graphics类
提供绘图的常用方法,可以实现直线、矩形、多边形、文字、图片等的绘制及其操作,包括颜色、字体、画笔、文本、图像等;
2.Graphics2D类
提供更强大的绘图功能
Graphics类可强转为 Graphics2D类
3.Graphics类常用方法
draw(int x,int y,int height,int startAngle,int arcAngle) //弧形
drawLine(int x1,int y1,int x2,int y2) //直线
drawOval(int x,int y,int width,int height) //椭圆
drawPolygon(int[] xPoints,int[] yPoints,int nPoints) //多边形
drawPolyline(int[] xPoints,int[] yPoints,int nPoints) //多边线
drawRect(int x,int y,int width,int height) //矩形
drawRoundRect(int x,int y,int width,int height,int arcWidth,int arcAngle) //圆角矩形
fillArc(int x,int y,int width,int height,int startAngle,int arcAngle) //实心弧形
fillOval(int x,int y,int width,int height) //实心椭圆
fillPolygon(int[] xPoints,int[] yPoints,int nPoints) //实心多边形
fillRect(int x,int y,int width,int height) //实心矩形
fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight) //实心圆角矩形
当我们要绘制图形时,我们必须要进行创建并初始化图形类对象。这些图形必须时Shape接口的实现类,然后使用Graphics2D类的draw方法进行绘制,或者fill方法进行填充。
/**
* 画图,Paint
*/
public class D08Paint {
public static void main(String[] args) {
new PaintFrame().loadFrame();
}
}
class PaintFrame extends Frame{
//绘图窗口设置
public void loadFrame(){
setSize(500,300);
setTitle("Paint");
setLocationRelativeTo(null);
setVisible(true);
}
//画图函数
@Override
public void paint(Graphics g) {
Graphics2D g2d=(Graphics2D
g.setColor(Color.RED);
g.drawOval(100,100,200,100);
g.fillOval(200,100,50,50);
g.fill3DRect(300,200,50,50,true);
//画图像
try {
g.drawImage(ImageIO.read(new File("//images/1.jpg")),100,100,null);
} catch (IOException e) {
e.printStackTrace();
}
}
}
8.鼠标监听
/**
* 画点
* Point类、ArrayList、鼠标监听事件
*/
public class D09MouseListener {
public static void main(String[] args) {
new MouseFrame("画图");
}
}
//主窗体,添加监听时间
class MouseFrame extends Frame{
ArrayList<Point> points=new ArrayList();
Point tempPoint;
public MouseFrame(String title){
super(title);
setSize(500,300);
setLocationRelativeTo(null);
setVisible(true);
//鼠标监听器
this.addMouseListener(new MyMouseListener());
}
@Override
public void paint(Graphics g) {
g.setColor(Color.GREEN);
Iterator iterator=points.iterator();
while(iterator.hasNext()){
tempPoint=(Point)iterator.next();
g.fillOval(tempPoint.x,tempPoint.y,5,5);
}
}
//内部类,写自己的监听器,适配器模式
private class MyMouseListener extends MouseAdapter{
//鼠标按下、弹起、按住不放
@Override
public void mousePressed(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
}
}
9.窗口监听
/**
* 窗口监听事件
*/
public class D10WindowListener {
public static void main(String[] args) {
new WinFrame();
}
}
class WinFrame extends Frame{
public WinFrame(){
setTitle("WindowListener");
setBackground(Color.cyan);
setSize(600,400);
setLocationRelativeTo(null);
setVisible(true);
addWindowListener(new WindowAdapter(){ //匿名内部类
@Override //窗口打开
public void windowOpened(WindowEvent e) {
System.out.println("windowOpened");
}
@Override //关闭中
public void windowClosing(WindowEvent e) {
System.out.println("windowClosing");
}
@Override //已关闭
public void windowClosed(WindowEvent e) {
System.out.println("windowClosed");
}
@Override //图标化窗口
public void windowIconified(WindowEvent e) {
System.out.println("windowIconified");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("windowDeiconified");
}
@Override //窗口激活,鼠标进入
public void windowActivated(WindowEvent e) {
System.out.println("windowActivated");
}
@Override //鼠标离开
public void windowDeactivated(WindowEvent e) {
System.out.println("windowDeactivated");
}
@Override //窗口状态:激活、待机
public void windowStateChanged(WindowEvent e) {
System.out.println("windowStateChanged");
}
@Override //鼠标移入
public void windowGainedFocus(WindowEvent e) {
System.out.println("windowGainedFocus");
}
@Override //鼠标溢出
public void windowLostFocus(WindowEvent e) {
System.out.println("windowLostFocus");
}
});
}
}
10.键盘监听事件
/**
* 键盘监听
*/
public class D10KeyListener {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame{
public KeyFrame(){
setSize(500,300);
setLocationRelativeTo(null);
setVisible(true);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
Character ch=e.getKeyChar();
int code=e.getKeyCode();
System.out.println(ch+":"+code);
if(code==KeyEvent.VK_UP){
System.out.println("你按下了向上键");
}
}
});
}
}
本文来自博客园,作者:老李学Java,转载请注明原文链接:https://www.cnblogs.com/JasonPro/p/16058316.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构