Java基础学习总结(23)——GUI编程
一、AWT介绍
所有的可以显示出来的图形元素都称为Component,Component代表了所有的可见的图形元素,Component里面有一种比较特殊的图形元素叫Container,Container(容器)在图形界面里面是一种可以容纳其它Component元素的一种容器,Container本身也是一种Component的,Container里面也可以容纳别的Container。
Container里面又分为Window和Pannel,Window是可以独立显示出来的,平时我们看到的各种各样的应用程序的窗口都可以称为Window,Window作为一个应用程序窗口独立显示出来,Pannel也可以容纳其它的图形元素,但一般看不见Pannel,Pannel不能作为应用程序的独立窗口显示出来,Pannel要想显示出来就必须得把自己装入到Window里面才能显示出来。
Pannel应用比较典型的就是Applet(JAVA的页面小应用程序),现在基本上已经不用了,AJAX和JAVASCRIPT完全取代了它的应用。
Window本身又可以分为Frame和Dialog,Frame就是我们平时看到的一般的窗口,而Dialog则是那些需要用户进行了某些操作(如点击某个下拉菜单的项)才出现的对话框,这种对话框就是Dialog。
二、组件和容器(Component和Container)
2.1.Frame
Frame范例:
1 package cn.javastudy.summary;
2
3 /**学习JAVA的GUI编程编写的第一个图形界面窗口*/
4 import java.awt.*;
5
6 public class TestFrame {
7 public static void main(String args[]) {
8 Frame f = new Frame("我的第一个JAVA图形界面窗口");
9 /*
10 * 这里只是在内存里面创建了一个窗口对象 还不能真正显示出来然我们看到
11 */
12 f.setBackground(Color.blue);// 设置窗体的背景颜色
13 // blue是Color类里面的一个静态常量,可以使用“类名.静态常量名”来访问
14 f.setVisible(true);// 设置窗体是否可见
15 /*
16 * 要想看到在内存里面创建出来的窗口对象, 必须调用setVisble()方法,并且把参数true传入才能看得见窗体 如果传入的参数是false,那么窗体也是看不见的
17 */
18 f.setSize(400, 400);// 设置窗体的初始大小
19 f.setLocation(200, 200);// 设置窗体出现时的位置,如果不设置则默认在左上角(0,0)位置显示
20 f.setResizable(false);
21 /*
22 * 设置窗体能否被改变大小,设置为false后表示不能改变窗体的显示大小 这里将窗体显示的大小设置为200X200,那么窗体的显示只能是这个大小了,不能再使用鼠标拖大或者缩小
23 */
24 }
25 }
运行结果如下:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestMultiFrame{
5 public static void main(String args[]){
6 MyFrame f1 = new MyFrame(100,100,200,200,Color.BLUE);
7 MyFrame f2 = new MyFrame(300,100,200,200,Color.YELLOW);
8 MyFrame f3 = new MyFrame(100,300,200,200,Color.GREEN);
9 MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA);
10 }
11 }
12 /*自定义一个类MyFrame,并且从Frame类继承
13 这样MyFrame类就拥有了Frame类的一切属性和方法
14 并且MyFrame类还可以自定义属性和方法
15 因此使用从Frame类继承而来的自定义类来创建图形窗口比直接使用Frame类来创建图形窗口要灵活
16 所以一般使用从Frame类继承而来的自定义类创建图形窗口界面比较好,
17 不推荐直接使用Frame类来创建图形窗口界面
18 */
19 class MyFrame extends Frame{
20 static int id = 0;
21 //定义一个静态成员变量id,用来记录创建出来的窗口的数目
22 MyFrame(int x,int y,int w,int h,Color color){
23 //自定义构成方法,在构造方法体内使用super调用父类Frame的构造方法
24 super("MyFrame"+(++id));
25 setBackground(color);
26 /*使用从父类Frame继承而来的方法设置窗体的相关属性*/
27 setLayout(null);
28 setBounds(x,y,w,h);
29 setVisible(true);
30 }
31 }
运行结果:
2.2.Panel
Panel范例:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestPanel{
5 public static void main(String args[]){
6 Frame f = new Frame("JAVA Fram With Panel");
7 Panel p = new Panel(null);
8 f.setLayout(null);
9 f.setBounds(300,300,500,500);//这里设置的坐标(300,300)是相对于整个屏幕的
10 f.setBackground(new Color(0,0,102));//设置背景颜色时使用三基色(红,绿,蓝)的比例来调配背景色
11 p.setBounds(50,50,400,400);//这里设置的坐标(50,50)是相对于Frame窗体的
12 p.setBackground(new Color(204,204,255));
13 f.add(p);//把Panel容器装入到Frame容器中,使其能在Frame窗口中显示出来
14 f.setVisible(true);
15 }
16 }
运行结果如下:
三、布局管理器
3.1.第一种布局管理器——FlowLayout
测试代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestFlowLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("FlowLayout");
8 /*
9 * 使用Button类创建按钮 按钮类的其中一个构造方法:Button(String label) label为按钮显示的文本
10 */
11 Button btn1 = new Button("button1");
12 Button btn2 = new Button("button2");
13 Button btn3 = new Button("button3");
14 /* setLayout方法的定义:public void setLayout(LayoutManager mgr) */
15 f.setLayout(new FlowLayout());// 使用流水(Flow)线般的布局
16 /* 使用了布局管理器FlowLayout,这里的布局采用默认的水平居中模式 */
17 // f.setLayout(new FlowLayout(FlowLayout.LEFT));
18 /* 这里在布局的时候使用了FlowLayout.LEFT常量,这样就将按钮设置为左对齐 */
19 // f.setLayout(new FlowLayout(FlowLayout.RIGHT));
20 /* 这里在布局的时候使用了FlowLayout.RIGHT常量,这样就将按钮设置为右对齐 */
21 f.add(btn1);// 把创建出来的按钮放置到Frame窗体中
22 f.add(btn2); // 这里并没有设置按钮的大小与位置
23 f.add(btn3); // 设置按钮的大小与位置都是由布局管理器来做的
24 f.setVisible(true);
25 f.setSize(200, 200);
26 }
27 }
运行结果如下:
3.2.第二种布局管理器——BorderLayout
测试代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestBorderLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("BorderLayout");
8 Button btnEast = new Button("East");
9 Button btnWest = new Button("West");
10 Button btnSouth = new Button("South");
11 Button btnNorth = new Button("North");
12 Button btnCenter = new Button("Center");
13 /*
14 * 把按钮放置到Frame窗体时按照东西南北中五个方向排列好 推荐使用这种方式去排列窗体元素,
15 * 这样容易检查出错误 因为这样写如果写错了编译器会提示出错
16 */
17 f.add(btnEast, BorderLayout.EAST);
18 f.add(btnWest, BorderLayout.WEST);
19 f.add(btnSouth, BorderLayout.SOUTH);
20 f.add(btnNorth, BorderLayout.NORTH);
21 f.add(btnCenter, BorderLayout.CENTER);
22 /*
23 * 也可以使用这样的方式排列按钮 在把按钮放置到Frame窗体时使用方向定位的字符串指定按钮的放置位置
24 * 这种使用方向定位的字符串指定按钮的放置方式不推荐使用 一旦写错了方向字符串就不好检查出来
25 * 因为即使是写错了仍然可以编译通过
26 */
27 /*
28 * f.add(btnEast,"East");
29 * f.add(btnWest,"West");
30 * f.add(btnSouth,"South");
31 * f.add(btnNorth,"North");
32 * f.add(btnCenter,"Center");
33 */
34 f.setSize(200, 200);
35 f.setVisible(true);
36 }
37 }
运行结果:
3.3.第三种布局管理器——GridLayout(表格布局管理器)
测试代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4
5 public class TestGridLayout {
6 public static void main(String args[]) {
7 Frame f = new Frame("GridLayout");
8 Button btn1 = new Button("btn1");
9 Button btn2 = new Button("btn2");
10 Button btn3 = new Button("btn3");
11 Button btn4 = new Button("btn4");
12 Button btn5 = new Button("btn5");
13 Button btn6 = new Button("bnt6");
14 f.setLayout(new GridLayout(3, 2));
15 /* 把布局划分成3行2列的表格布局形式 */
16 f.add(btn1);
17 f.add(btn2);
18 f.add(btn3);
19 f.add(btn4);
20 f.add(btn5);
21 f.add(btn6);
22 f.pack();
23 f.setVisible(true);
24 }
25 }
运行结果:
3.4.布局练习
这几种布局管理器可以设置在Frame里面,也可以设置在Panel里面,而Panel本身也可以加入到Frame里面,因此通过Frame与Panel的嵌套就可以实现比较复杂的布局
实现代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestTenButtons{
5 public static void main(String args[]){
6 /*这里主要是对显示窗体进行设置*/
7 Frame f = new Frame("布局管理器的嵌套使用");
8 f.setLayout(new GridLayout(2,1));//把整个窗体分成2行1列的表格布局
9 f.setLocation(300,400);
10 f.setSize(400,300);
11 f.setVisible(true);
12 f.setBackground(new Color(204,204,255));
13 /*这里主要是对Panel进行布局的设置*/
14 Panel p1 = new Panel(new BorderLayout());
15 Panel p2 = new Panel(new GridLayout(2,1));//p2使用2行1列的表格布局
16 Panel p3 = new Panel(new BorderLayout());
17 Panel p4 = new Panel(new GridLayout(2,2));//p4使用2行2列的表格布局
18 /*这里主要是把按钮元素加入到Panel里面*/
19 p1.add(new Button("East(p1-东)"),BorderLayout.EAST);
20 p1.add(new Button("West(p1-西)"),BorderLayout.WEST);
21 p2.add(new Button("p2-Button1"));
22 p2.add(new Button("p2-Button2"));
23 /*p1里面嵌套p2,把p2里面的按钮作为p的中间部分装入到p1里面*/
24 p1.add(p2,BorderLayout.CENTER);//把p2作为元素加入到p1里面
25
26 p3.add(new Button("East(p3-东)"),BorderLayout.EAST);
27 p3.add(new Button("West(p3-西)"),BorderLayout.WEST);
28 for(int i=0;i<4;i++){
29 p4.add(new Button("p4-Button"+i));
30 }
31 /*p3里面嵌套p4,把p4里面的按钮作为p的中间部分装入到p3里面*/
32 p3.add(p4,BorderLayout.CENTER);
33
34 f.add(p1);//把Panel装入Frame里面,以便于在Frame窗体中显示出来
35 f.add(p3);
36
37 }
38 }
运行结果:
四、布局管理器总结
一、事件监听
测试代码一:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestActionEvent {
7 public static void main(String args[]) {
8 Frame f = new Frame("TestActionEvent");
9 Button btn = new Button("Press Me");
10 Monitor m = new Monitor();/* 创建一个监听对象 */
11 btn.addActionListener(m);
12 /*
13 * 把监听加入到按钮里面,监听按钮的动作, 当按钮触发打击事件时,就会返回一个监听对象e 然后就会自动执行actionPerformed方法
14 */
15 f.add(btn, BorderLayout.CENTER);
16 f.pack();
17 addWindowClosingEvent(f);
18 /* 调用这个方法可以自动给Frame窗体里面的子图形元素一个合适的初始大小 */
19 f.setVisible(true);
20 }
21
22 /**
23 * 点击窗体上的关闭按钮关闭窗体
24 * @param f
25 */
26 private static void addWindowClosingEvent(Frame f){
27 f.addWindowListener(new WindowAdapter() {
28 @Override
29 public void windowClosing(WindowEvent arg0) {
30 System.exit(0);
31 }
32
33 });
34 }
35 }
36
37 /*
38 * 自定义Monitor(监听)类实现事件监听接口ActionListener 一个类要想成为监听类,那么必须实现ActionListener接口
39 */
40 class Monitor implements ActionListener {
41 /* 重写ActionListener接口里面的actionPerformed(ActionEvent e)方法 */
42 public void actionPerformed(ActionEvent e) {
43 System.out.println("A Button has been Pressed");
44 }
45 }
测试代码二:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestActionEvent2{
6 public static void main(String args[]){
7 Frame f = new Frame("TestActionEvent");
8 Button btn1 = new Button("start");
9 Button btn2 = new Button("stop");
10 Monitor2 m2 = new Monitor2();//创建监听对象
11 btn1.addActionListener(m2);
12 /*一个监听对象同时监听两个按钮的动作*/
13 btn2.addActionListener(m2);
14 btn2.setActionCommand("GameOver");//设置btn2的执行单击命令后的返回信息
15 f.add(btn1,BorderLayout.NORTH);
16 f.add(btn2,BorderLayout.CENTER);
17
18 f.pack();
19 f.setVisible(true);
20 }
21 }
22
23 class Monitor2 implements ActionListener{
24 public void actionPerformed(ActionEvent e){
25 System.out.println("a button has been pressed,"+"the relative info is:\n"+e.getActionCommand());
26 /*使用返回的监听对象e调用getActionCommand()方法获取两个按钮执行单击命令后的返回信息
27 根据返回信息的不同区分开当前操作的是哪一个按钮,btn1没有使用setActionCommand()方法设置
28 则btn1返回的信息就是按钮上显示的文本*/
29 }
30 }
二、TextField事件监听
测试代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestTextField {
7 public static void main(String args[]) {
8 new MyFrameTextField();
9 }
10 }
11
12 class MyFrameTextField extends Frame {
13 MyFrameTextField() {
14 TextField tf = new TextField();
15 add(tf);
16 tf.addActionListener(new Monitor3());
17 tf.setEchoChar('*');
18 /*
19 * 这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*,
20 * 这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容
21 */
22 setVisible(true);
23 pack();
24 }
25 }
26
27 class Monitor3 implements ActionListener {
28 /*
29 * 接口里面的所有方法都是public(公共的)
30 * 所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上public
31 */
32 public void actionPerformed(ActionEvent e) {
33 /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */
34 TextField tf = (TextField) e.getSource();
35 /*
36 * getSource()方法是拿到事件源,注意:拿到这个事件源的时候,
37 * 是把它当作TextField的父类来对待
38 * getSource()方法的定义是:“public Object getSource()”返回值是一个Object对象,
39 * 所以要强制转换成TextField类型的对象
40 * 在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法
41 */
42 System.out.println(tf.getText());// tf.getText()是取得文本框里面的内容
43 tf.setText("");// 把文本框里面的内容清空
44 }
45 }
使用TextField类实现简单的计算器
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath {
7 public static void main(String args[]) {
8 new TFFrame();
9 }
10 }
11
12 /* 这里主要是完成计算器元素的布局 */
13 class TFFrame extends Frame {
14 TFFrame() {
15 /*
16 * 创建3个文本框,并指定其初始大小分别为10个字符和15个字符的大小 这里使用的是TextField类的另外一种构造方法 public TextField(int columns)
17 */
18 TextField num1 = new TextField(10);
19 TextField num2 = new TextField(10);
20 TextField num3 = new TextField(15);
21 /* 创建等号按钮 */
22 Button btnEqual = new Button("=");
23 btnEqual.addActionListener(new MyMonitor(num1, num2, num3));
24 /* 给等号按钮加上监听,让点击按钮后有响应事件发生 */
25 Label lblPlus = new Label("+");
26 /* “+”是一个静态文本,所以使用Label类创建一个静态文本对象 */
27 setLayout(new FlowLayout());
28 /* 把Frame默认的BorderLayout布局改成FlowLayout布局 */
29 add(num1);
30 add(lblPlus);
31 add(num2);
32 add(btnEqual);
33 add(num3);
34 pack();
35 setVisible(true);
36
37 }
38 }
39
40 class MyMonitor implements ActionListener {
41 TextField num1, num2, num3;
42
43 /*
44 * 为了使对按钮的监听能够对文本框也起作用,
45 * 所以在自定义类MyMonitor里面定义三个TextField类型的对象 num1,num2,num3,
46 * 并且定义了MyMonitor类的一个构造方法 这个构造方法带有三个TextField类型的参数,
47 * 用于接收 从TFFrame类里面传递过来的三个TextField类型的参数
48 * 然后把接收到的三个TextField类型的参数赋值给在本类中声明的 三个TextField类型的参数num1,num2,num3 然后再在actionPerformed()方法里面处理num1,num2,num3
49 */
50 public MyMonitor(TextField num1, TextField num2, TextField num3) {
51 this.num1 = num1;
52 this.num2 = num2;
53 this.num3 = num3;
54 }
55
56 public void actionPerformed(ActionEvent e) {
57 /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */
58 int n1 = Integer.parseInt(num1.getText());/* num1对象调用getText()方法取得自己显示的文本字符串 */
59 int n2 = Integer.parseInt(num2.getText());/* num2对象调用getText()方法取得自己显示的文本字符串 */
60 num3.setText("" + (n1 + n2));/* num3对象调用setText()方法设置自己的显示文本 */
61 num1.setText("");
62 /* 计算结束后清空num1,num2文本框里面的内容 */
63 num2.setText("");
64 // num3.setText(String.valueOf((n1+n2)));
65 /* 字符串与任意类型的数据使用“+”连接时得到的一定是字符串,
66 * 这里使用一个空字符串与int类型的数连接,这样就可以直接把(n1+n2)得到的int类型的数隐式地转换成字符串了,
67 * 这是一种把别的基础数据类型转换成字符串的一个小技巧。
68 * 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和转换成字符串
69 */
70 }
71 }
JAVA里面的经典用法:在一个类里面持有另外一个类的引用
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath1 {
7 public static void main(String args[]) {
8 new TTMyFrame().launchFrame();
9 /* 创建出TTMyFrame对象后调用lauchFrame()方法把计算器窗体显示出来 */
10 }
11 }
12
13 /* 做好计算器的窗体界面 */
14 class TTMyFrame extends Frame {
15 /* 把设计计算器窗体的代码封装成一个方法 */
16 TextField num1, num2, num3;
17
18 public void launchFrame() {
19 num1 = new TextField(10);
20 num2 = new TextField(15);
21 num3 = new TextField(15);
22 Label lblPlus = new Label("+");
23 Button btnEqual = new Button("=");
24 btnEqual.addActionListener(new MyMonitorbtnEqual(this));
25 setLayout(new FlowLayout());
26 add(num1);
27 add(lblPlus);
28 add(num2);
29 add(btnEqual);
30 add(num3);
31 pack();
32 setVisible(true);
33 }
34 }
35
36 /*
37 * 这里通过取得TTMyFrame类的引用,然后使用这个引用去访问TTMyFrame类里面的成员变量
38 * 这种做法比上一种直接去访问TTMyFrame类里面的成员变量要好得多,
39 * 因为现在不需要知道 TTMyFrame类里面有哪些成员变量了,
40 * 现在要访问TTMyFrame类里面的成员变量,直接使用 TTMyFrame类对象的引用去访问即可,
41 * 这个TTMyFrame类的对象好比是一个大管家, 而我告诉大管家,我要访问TTMyFrame类里面的那些成员变量,
42 * 大管家的引用就会去帮我找,不再需要我自己去找了。
43 * 这种在一个类里面持有另一个类的引用的用法是一种非常典型的用法
44 * 使用获取到的引用就可以在一个类里面访问另一个类的所有成员了
45 */
46 class MyMonitorbtnEqual implements ActionListener {
47 TTMyFrame ttmf = null;
48
49 public MyMonitorbtnEqual(TTMyFrame ttmf) {
50 this.ttmf = ttmf;
51 }
52
53 public void actionPerformed(ActionEvent e) {
54 int n1 = Integer.parseInt(ttmf.num1.getText());
55 int n2 = Integer.parseInt(ttmf.num2.getText());
56 ttmf.num3.setText("" + (n1 + n2));
57 ttmf.num1.setText("");
58 ttmf.num2.setText("");
59 }
60 }
运行结果如下:
三、内部类
内部类的使用范例:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 import java.awt.event.*;
5
6 public class TestMath3 {
7
8 public static void main(String args[]) {
9 new MyMathFrame().launchFrame();
10 }
11 }
12
13 class MyMathFrame extends Frame {
14 TextField num1, num2, num3;
15
16 public void launchFrame() {
17 num1 = new TextField(10);
18 num2 = new TextField(15);
19 num3 = new TextField(15);
20 Label lblPlus = new Label("+");
21 Button btnEqual = new Button("=");
22 btnEqual.addActionListener(new MyMonitor());
23 setLayout(new FlowLayout());
24 add(num1);
25 add(lblPlus);
26 add(num2);
27 add(btnEqual);
28 add(num3);
29 pack();
30 setVisible(true);
31 }
32
33 /*
34 * 这个MyMonitor类是内部类,它在MyFrame类里面定义 MyFrame类称为MyMonitor类的包装类
35 */
36 /*
37 * 使用内部类的好处:
38 * 第一个巨大的好处就是可以畅通无阻地访问外部类(即内部类的包装类)的所有成员变量和方法
39 * 如这里的在MyFrame类(外部类)定义的三个成员变量num1,num2,num3,
40 * 在MyMonitor(内部类)里面就可以直接访问
41 * 这相当于在创建外部类对象时内部类对象默认就拥有了一个外部类对象的引用
42 */
43 private class MyMonitor implements ActionListener {
44 public void actionPerformed(ActionEvent e) {
45 int n1 = Integer.parseInt(num1.getText());
46 int n2 = Integer.parseInt(num2.getText());
47 num3.setText("" + (n1 + n2));
48 num1.setText("");
49 num2.setText("");
50 }
51 }
52 }
内部类带来的巨大好处是:
- 可以很方便地访问外部类定义的成员变量和方法
- 当某一个类不需要其他类访问的时候就把这个类声明为内部类。
四、Graphics 类
测试代码:
1 package cn.javastudy.summary;
2
3 import java.awt.*;
4 public class TestPaint{
5 public static void main(String args[]){
6 new MyPaint().launchFrame();
7 /*在main()方法里面并没有显示调用paint(Graphics g)方法
8 可是当创建出Frame窗体后却可以看到Frame窗体上画出了
9 圆和矩形,这是因为paint()方法是一个比较特殊的方法
10 在创建Frame窗体时会自动隐式调用
11 当我们把Frame窗体最小化又再次打开时,又会再次调用
12 paint()方法重新把圆和矩形在Frame窗体上画出来
13 即每次需要重画Frame窗体的时候就会自动调用paint()方法*/
14 }
15 }
16
17 class MyPaint extends Frame{
18 public void launchFrame(){
19 setBounds(200,200,640,480);
20 setVisible(true);
21 }
22
23 public void paint(Graphics g){
24 /*paint(Graphics g)方法有一个Graphics类型的参数g
25 我们可以把这个g当作是一个画家,这个画家手里拿着一只画笔
26 我们通过设置画笔的颜色与形状来画出我们想要的各种各样的图像*/
27 /*设置画笔的颜色*/
28 g.setColor(Color.red);
29 g.fillOval(100,100,100,100);/*画一个实心椭圆*/
30 g.setColor(Color.green);
31 g.fillRect(150,200,200,200);/*画一个实心矩形*/
32 /*这下面的两行代码是为了写程序的良好编程习惯而写的
33 前面设置了画笔的颜色,现在就应该把画笔的初始颜色恢复过来
34 就相当于是画家用完画笔之后把画笔上的颜色清理掉一样*/
35 Color c = g.getColor();
36 g.setColor(c);
37 }
38 }
运行结果:
五、鼠标事件适配器
测试代码:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import java.util.*;
6 public class MyMouseAdapter{
7 public static void main(String args[]) {
8 new MyFrame("drawing...");
9 }
10 }
11
12 class MyFrame extends Frame {
13 ArrayList points = null;
14 MyFrame(String s) {
15 super(s);
16 points = new ArrayList();
17 setLayout(null);
18 setBounds(300,300,400,300);
19 this.setBackground(new Color(204,204,255));
20 setVisible(true);
21 this.addMouseListener(new Monitor());
22 }
23
24 public void paint(Graphics g) {
25 Iterator i = points.iterator();
26 while(i.hasNext()){
27 Point p = (Point)i.next();
28 g.setColor(Color.BLUE);
29 g.fillOval(p.x,p.y,10,10);
30
31 }
32 }
33
34 public void addPoint(Point p){
35 points.add(p);
36 }
37 }
38
39 class Monitor extends MouseAdapter {
40 public void mousePressed(MouseEvent e) {
41 MyFrame f = (MyFrame)e.getSource();
42 f.addPoint(new Point(e.getX(),e.getY()));
43 f.repaint();
44 }
45 }
六、window事件
测试代码:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestWindowClose{
6 public static void main(String args[]){
7 new WindowFrame("关闭WindowFrame");
8 }
9 }
10
11 class WindowFrame extends Frame{
12 public WindowFrame(String s){
13 super(s);
14 setBounds(200,200,400,300);
15 setLayout(null);
16 setBackground(new Color(204,204,255));
17 setVisible(true);
18 this.addWindowListener(new WindowMonitor());
19 /*监听本窗体的动作,把所有的动作信息封装成一个对象传递到监听类里面*/
20
21 this.addWindowListener(
22 /*在一个方法里面定义一个类,这个类称为局部类,也叫匿名的内部类,
23 这里的{……代码……}里面的代码很像一个类的类体,只不过这个类没有名字,所以叫匿名类
24 在这里是把这个匿名类当成WindowAdapter类来使用,语法上这样写的本质意义是相当于这个匿名类
25 从WindowAdapter类继承,现在new了一个匿名类的对象出来然后把这个对象当成WindowAdapter来使用
26 这个匿名类出了()就没有人认识了*/
27 new WindowAdapter(){
28 public void windowClosing(WindowEvent e){
29 setVisible(false);
30 System.exit(-1);
31 }
32 }
33 );
34 }
35
36 /*这里也是将监听类定义为内部类*/
37 class WindowMonitor extends WindowAdapter{
38 /*WindowAdapter(Window适配器)类实现了WindowListener监听接口
39 重写了WindowListener接口里面的所有方法
40 如果直接使用自定义WindowMonitor类直接去
41 实现WindowListener接口,那么就得要重写WindowListener接口
42 里面的所有方法,但现在只需要用到这些方法里面的其中一个方法
43 所以采用继承实现WindowListener监听接口的一个子类
44 并重写这个子类里面需要用到的那个方法即可
45 这种做法比直接实现WindowListener监听接口要重写很多个用不到的方法要简洁方便得多*/
46 /*重写需要用到的windowClosing(WindowEvent e)方法*/
47 public void windowClosing(WindowEvent e){
48 setVisible(false);/*将窗体设置为不显示,即可实现窗体关闭*/
49 System.exit(0);/*正常退出*/
50 }
51 }
52 }
七、键盘响应事件——KeyEvent
测试代码:
1 package cn.galc.test;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 public class TestKeyEvent{
6 public static void main(String args[]){
7 new KeyFrame("键盘响应事件");
8 }
9 }
10
11 class KeyFrame extends Frame{
12 public KeyFrame(String s){
13 super(s);
14 setBounds(200,200,400,300);
15 setLayout(null);
16 setVisible(true);
17 addKeyListener(new KeyMonitor());
18 }
19 /*把自定义的键盘的监听类定义为内部类
20 这个监听类从键盘适配器KeyAdapter类继承
21 从KeyAdapter类继承也是为了可以简洁方便
22 只需要重写需要用到的方法即可,这种做法比
23 直接实现KeyListener接口要简单方便,如果
24 直接实现KeyListener接口就要把KeyListener
25 接口里面的所有方法重写一遍,但真正用到的
26 只有一个方法,这样重写其他的方法但又用不到
27 难免会做无用功*/
28 class KeyMonitor extends KeyAdapter{
29 public void keyPressed(KeyEvent e){
30 int keycode = e.getKeyCode();
31 /*使用getKeyCode()方法获取按键的虚拟码*/
32 /*如果获取到的键的虚拟码等于up键的虚拟码
33 则表示当前按下的键是up键
34 KeyEvent.VK_UP表示取得up键的虚拟码
35 键盘中的每一个键都对应有一个虚拟码
36 这些虚拟码在KeyEvent类里面都被定义为静态常量
37 所以可以使用“类名.静态常量名”的形式访问得到这些静态常量*/
38 if(keycode == KeyEvent.VK_UP){
39 System.out.println("你按的是up键");
40 }
41 }
42 }
43 }
44 /*键盘的处理事件是这样的:每一个键都对应着一个虚拟的码,
45 当按下某一个键时,系统就会去找这个键对应的虚拟的码,以此来确定当前按下的是那个键
46 */
Java基础学习总结(23)——GUI编程的更多相关文章
- Java学习之AWT GUI编程
Java学习之AWT GUI编程 0x00 前言 既然前面提到了要重写冰蝎和一些反序列化工具,当然就不能随便说说而已.在编写这些工具还是要使用图形化工具来的方便一些,所以提前把GUI的框架给学习一遍. ...
- Java学习之Swing Gui编程
Java学习之Swing Gui编程 0x00 前言 前面的使用的Gui是基于Awt 去进行实现,但是在现实写Gui中 AWT实际运用会比较少. 0x01 Swing 概述 AWT 和Swing 区别 ...
- 转载-java基础学习汇总
共2页: 1 2 下一页 Java制作证书的工具keytool用法总结 孤傲苍狼 2014-06-24 11:03 阅读:25751 评论:3 Java基础学习总结——Java对象的序列化和 ...
- 尚学堂JAVA基础学习笔记
目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...
- Java基础学习笔记总结
Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...
- JAVA基础学习-集合三-Map、HashMap,TreeMap与常用API
森林森 一份耕耘,一份收获 博客园 首页 新随笔 联系 管理 订阅 随笔- 397 文章- 0 评论- 78 JAVA基础学习day16--集合三-Map.HashMap,TreeMap与常用A ...
- [转帖]java基础学习总结——多态(动态绑定)
https://www.cnblogs.com/xdp-gacl/p/3644035.html 多态的概念 java基础学习总结——多态(动态绑定) 一.面向对象最核心的机制——动态绑定,也叫多态
- java基础学习笔记五(抽象类)
java基础学习总结——抽象类 抽象类介绍
- Java基础学习-- 继承 的简单总结
代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...
- Java基础学习中一些词语和语句的使用
在Java基础学习中,我们刚接触Java会遇到一些词和语句的使用不清的情况,不能很清楚的理解它的运行效果会是怎么样的,如:break,continue在程序中运行效果及跳转位置, 1.先来看看brea ...
随机推荐
- 51nod 1307 绳子与重物 (标记父节点更新即可)
1307 绳子与重物 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有N条绳子编号 0 至 N - 1,每条绳子后面栓了一个重物重量为Wi,绳子的最大负重为Ci. ...
- 哪位大兄弟有用 cMake 开发Android ndk的
一直用 Android studio 开发ndk,但是gradle支持的不是很好,只有experimental 版本支持 配置各种蛋疼.主要每次新建一个module都要修改配置半天.之前也看到过goo ...
- php如何实现文件下载
php如何实现文件下载 1. 设置超链接的href属性 <ahref="文件地址"></a> 如果浏览器不能解析该文件,浏览器会自动下载.而如果文件是图片或 ...
- 条件变量本质-Problem statement-while not( P ) do skip
条件变量相当于订阅-发布机制: 或者相当于同步的通知机制: 订阅和发布具有先后顺序:所以需要互斥量来维护顺序. 顺序不对,存在信号丢失问题. Problem statement[edit] For m ...
- 3ds Max 2018 在安装后无法启动或出现不稳定
问题: 安装 3ds Max 2018 后,软件无法正常启动,或在打开后不久出现不稳定和崩溃. 原因: 有多种原因可能会导致这些错误: ▪ 3ds Max.Windows 更新和 ProSound.d ...
- Calling Mojo from Blink
Variants Let's assume we have a mojom file such as this: module example.mojom; interface Foo { ...
- VC++ 借助 Win32 API 绘图实现基本的细胞自动机演示
//本程序使用 Visual Studio 2015 生成的 Win32 窗口程序模板 开发//使用 Win32 API 绘图//实现基本的细胞自动机演示////目前已知问题://存在内存泄漏,但具体 ...
- Nginx 禁止 ip 访问
server { listen 80 default_server; server_name _; access_log /logs/ip-access.log main; error_log /lo ...
- [洛谷P1835]素数密度
题目大意:求区间[l,r]中素数的个数($1\leq l,r\le 2^{31}$,$r-l\leq 10^6$). 解题思路:首先,用筛法筛出$2~\sqrt{r}$内的素数. 然后用这些素数筛l~ ...
- python 退出程序的执行
使用sys.exit()退出当前程序的执行 import sys if x==0: sys.exit()