首页 > 代码库 > java基础学习总结——GUI编程(二)

java基础学习总结——GUI编程(二)

一、事件监听

  

测试代码一:

 
 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 f25      */26     private static void addWindowClosingEvent(Frame f){27         f.addWindowListener(new WindowAdapter() {28             @Override29             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前面加上public31      */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,num349      */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 }
 

内部类带来的巨大好处是:

  1. 可以很方便地访问外部类定义的成员变量和方法
  2. 当某一个类不需要其他类访问的时候就把这个类声明为内部类。

四、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类型的参数g25         我们可以把这个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事件