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 1 package cn.javastudy.summary; 2 2 3 3 /**学习JAVA的GUI编程编写的第一个图形界面窗口*/ 4 4 import java.awt.*; 5 5 6 6 public class TestFrame { 7 7 public static void main(String args[]) { 8 8 Frame f = new Frame("我的第一个JAVA图形界面窗口"); 9 9 /* 1010 * 这里只是在内存里面创建了一个窗口对象 还不能真正显示出来然我们看到 1111 */ 1212 f.setBackground(Color.blue);// 设置窗体的背景颜色 1313 // blue是Color类里面的一个静态常量,可以使用“类名.静态常量名”来访问 1414 f.setVisible(true);// 设置窗体是否可见 1515 /* 1616 * 要想看到在内存里面创建出来的窗口对象, 必须调用setVisble()方法,并且把参数true传入才能看得见窗体 如果传入的参数是false,那么窗体也是看不见的 1717 */ 1818 f.setSize(400, 400);// 设置窗体的初始大小 1919 f.setLocation(200, 200);// 设置窗体出现时的位置,如果不设置则默认在左上角(0,0)位置显示 2020 f.setResizable(false); 2121 /* 2222 * 设置窗体能否被改变大小,设置为false后表示不能改变窗体的显示大小 这里将窗体显示的大小设置为200X200,那么窗体的显示只能是这个大小了,不能再使用鼠标拖大或者缩小 2323 */ 2424 } 2525 }

复制代码

运行结果如下:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 public class TestMultiFrame{ 5 5 public static void main(String args[]){ 6 6 MyFrame f1 = new MyFrame(100,100,200,200,Color.BLUE); 7 7 MyFrame f2 = new MyFrame(300,100,200,200,Color.YELLOW); 8 8 MyFrame f3 = new MyFrame(100,300,200,200,Color.GREEN); 9 9 MyFrame f4 = new MyFrame(300,300,200,200,Color.MAGENTA); 1010 } 1111 } 1212 /*自定义一个类MyFrame,并且从Frame类继承 1313 这样MyFrame类就拥有了Frame类的一切属性和方法 1414 并且MyFrame类还可以自定义属性和方法 1515 因此使用从Frame类继承而来的自定义类来创建图形窗口比直接使用Frame类来创建图形窗口要灵活 1616 所以一般使用从Frame类继承而来的自定义类创建图形窗口界面比较好, 1717 不推荐直接使用Frame类来创建图形窗口界面 1818 */ 1919 class MyFrame extends Frame{ 2020 static int id = 0; 2121 //定义一个静态成员变量id,用来记录创建出来的窗口的数目 2222 MyFrame(int x,int y,int w,int h,Color color){ 2323 //自定义构成方法,在构造方法体内使用super调用父类Frame的构造方法 2424 super("MyFrame"+(++id)); 2525 setBackground(color); 2626 /*使用从父类Frame继承而来的方法设置窗体的相关属性*/ 2727 setLayout(null); 2828 setBounds(x,y,w,h); 2929 setVisible(true); 3030 } 3131 }

复制代码

运行结果:

2.2.Panel

Panel范例:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 public class TestPanel{ 5 5 public static void main(String args[]){ 6 6 Frame f = new Frame("JAVA Fram With Panel"); 7 7 Panel p = new Panel(null); 8 8 f.setLayout(null); 9 9 f.setBounds(300,300,500,500);//这里设置的坐标(300,300)是相对于整个屏幕的 1010 f.setBackground(new Color(0,0,102));//设置背景颜色时使用三基色(红,绿,蓝)的比例来调配背景色 1111 p.setBounds(50,50,400,400);//这里设置的坐标(50,50)是相对于Frame窗体的 1212 p.setBackground(new Color(204,204,255)); 1313 f.add(p);//把Panel容器装入到Frame容器中,使其能在Frame窗口中显示出来 1414 f.setVisible(true); 1515 } 1616 }

复制代码

运行结果如下:

三、布局管理器

3.1.第一种布局管理器——FlowLayout

测试代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 5 5 public class TestFlowLayout { 6 6 public static void main(String args[]) { 7 7 Frame f = new Frame("FlowLayout"); 8 8 /* 9 9 * 使用Button类创建按钮 按钮类的其中一个构造方法:Button(String label) label为按钮显示的文本 1010 */ 1111 Button btn1 = new Button("button1"); 1212 Button btn2 = new Button("button2"); 1313 Button btn3 = new Button("button3"); 1414 /* setLayout方法的定义:public void setLayout(LayoutManager mgr) */ 1515 f.setLayout(new FlowLayout());// 使用流水(Flow)线般的布局 1616 /* 使用了布局管理器FlowLayout,这里的布局采用默认的水平居中模式 */ 1717 // f.setLayout(new FlowLayout(FlowLayout.LEFT)); 1818 /* 这里在布局的时候使用了FlowLayout.LEFT常量,这样就将按钮设置为左对齐 */ 1919 // f.setLayout(new FlowLayout(FlowLayout.RIGHT)); 2020 /* 这里在布局的时候使用了FlowLayout.RIGHT常量,这样就将按钮设置为右对齐 */ 2121 f.add(btn1);// 把创建出来的按钮放置到Frame窗体中 2222 f.add(btn2); // 这里并没有设置按钮的大小与位置 2323 f.add(btn3); // 设置按钮的大小与位置都是由布局管理器来做的 2424 f.setVisible(true); 2525 f.setSize(200, 200); 2626 } 2727 }

复制代码

运行结果如下:

3.2.第二种布局管理器——BorderLayout

测试代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 5 5 public class TestBorderLayout { 6 6 public static void main(String args[]) { 7 7 Frame f = new Frame("BorderLayout"); 8 8 Button btnEast = new Button("East"); 9 9 Button btnWest = new Button("West"); 1010 Button btnSouth = new Button("South"); 1111 Button btnNorth = new Button("North"); 1212 Button btnCenter = new Button("Center"); 1313 /* 1414 * 把按钮放置到Frame窗体时按照东西南北中五个方向排列好 推荐使用这种方式去排列窗体元素, 1515 * 这样容易检查出错误 因为这样写如果写错了编译器会提示出错 1616 */ 1717 f.add(btnEast, BorderLayout.EAST); 1818 f.add(btnWest, BorderLayout.WEST); 1919 f.add(btnSouth, BorderLayout.SOUTH); 2020 f.add(btnNorth, BorderLayout.NORTH); 2121 f.add(btnCenter, BorderLayout.CENTER); 2222 /* 2323 * 也可以使用这样的方式排列按钮 在把按钮放置到Frame窗体时使用方向定位的字符串指定按钮的放置位置 2424 * 这种使用方向定位的字符串指定按钮的放置方式不推荐使用 一旦写错了方向字符串就不好检查出来 2525 * 因为即使是写错了仍然可以编译通过 2626 */ 2727 /* 2828 * f.add(btnEast,"East"); 2929 * f.add(btnWest,"West"); 3030 * f.add(btnSouth,"South"); 3131 * f.add(btnNorth,"North"); 3232 * f.add(btnCenter,"Center"); 3333 */ 3434 f.setSize(200, 200); 3535 f.setVisible(true); 3636 } 3737 }

复制代码

运行结果:

3.3.第三种布局管理器——GridLayout(表格布局管理器)

测试代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 5 5 public class TestGridLayout { 6 6 public static void main(String args[]) { 7 7 Frame f = new Frame("GridLayout"); 8 8 Button btn1 = new Button("btn1"); 9 9 Button btn2 = new Button("btn2"); 1010 Button btn3 = new Button("btn3"); 1111 Button btn4 = new Button("btn4"); 1212 Button btn5 = new Button("btn5"); 1313 Button btn6 = new Button("bnt6"); 1414 f.setLayout(new GridLayout(3, 2)); 1515 /* 把布局划分成3行2列的表格布局形式 */ 1616 f.add(btn1); 1717 f.add(btn2); 1818 f.add(btn3); 1919 f.add(btn4); 2020 f.add(btn5); 2121 f.add(btn6); 2222 f.pack(); 2323 f.setVisible(true); 2424 } 2525 }

复制代码

运行结果:

3.4.布局练习

这几种布局管理器可以设置在Frame里面,也可以设置在Panel里面,而Panel本身也可以加入到Frame里面,因此通过Frame与Panel的嵌套就可以实现比较复杂的布局

实现代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 public class TestTenButtons{ 5 5 public static void main(String args[]){ 6 6 /*这里主要是对显示窗体进行设置*/ 7 7 Frame f = new Frame("布局管理器的嵌套使用"); 8 8 f.setLayout(new GridLayout(2,1));//把整个窗体分成2行1列的表格布局 9 9 f.setLocation(300,400); 1010 f.setSize(400,300); 1111 f.setVisible(true); 1212 f.setBackground(new Color(204,204,255)); 1313 /*这里主要是对Panel进行布局的设置*/ 1414 Panel p1 = new Panel(new BorderLayout()); 1515 Panel p2 = new Panel(new GridLayout(2,1));//p2使用2行1列的表格布局 1616 Panel p3 = new Panel(new BorderLayout()); 1717 Panel p4 = new Panel(new GridLayout(2,2));//p4使用2行2列的表格布局 1818 /*这里主要是把按钮元素加入到Panel里面*/ 1919 p1.add(new Button("East(p1-东)"),BorderLayout.EAST); 2020 p1.add(new Button("West(p1-西)"),BorderLayout.WEST); 2121 p2.add(new Button("p2-Button1")); 2222 p2.add(new Button("p2-Button2")); 2323 /*p1里面嵌套p2,把p2里面的按钮作为p的中间部分装入到p1里面*/ 2424 p1.add(p2,BorderLayout.CENTER);//把p2作为元素加入到p1里面 2525 2626 p3.add(new Button("East(p3-东)"),BorderLayout.EAST); 2727 p3.add(new Button("West(p3-西)"),BorderLayout.WEST); 2828 for(int i=0;i<4;i++){ 2929 p4.add(new Button("p4-Button"+i)); 3030 } 3131 /*p3里面嵌套p4,把p4里面的按钮作为p的中间部分装入到p3里面*/ 3232 p3.add(p4,BorderLayout.CENTER); 3333 3434 f.add(p1);//把Panel装入Frame里面,以便于在Frame窗体中显示出来 3535 f.add(p3); 3636 3737 } 3838 }

复制代码

运行结果:

四、布局管理器总结

一、事件监听

测试代码一:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 6 6 public class TestActionEvent { 7 7 public static void main(String args[]) { 8 8 Frame f = new Frame("TestActionEvent"); 9 9 Button btn = new Button("Press Me"); 1010 Monitor m = new Monitor();/* 创建一个监听对象 */ 1111 btn.addActionListener(m); 1212 /* 1313 * 把监听加入到按钮里面,监听按钮的动作, 当按钮触发打击事件时,就会返回一个监听对象e 然后就会自动执行actionPerformed方法 1414 */ 1515 f.add(btn, BorderLayout.CENTER); 1616 f.pack(); 1717 addWindowClosingEvent(f); 1818 /* 调用这个方法可以自动给Frame窗体里面的子图形元素一个合适的初始大小 */ 1919 f.setVisible(true); 2020 } 2121 2222 /** 2323 * 点击窗体上的关闭按钮关闭窗体 2424 * @param f 2525 */ 2626 private static void addWindowClosingEvent(Frame f){ 2727 f.addWindowListener(new WindowAdapter() { 2828 @Override 2929 public void windowClosing(WindowEvent arg0) { 3030 System.exit(0); 3131 } 3232 3333 }); 3434 } 3535 } 3636 3737 /* 3838 * 自定义Monitor(监听)类实现事件监听接口ActionListener 一个类要想成为监听类,那么必须实现ActionListener接口 3939 */ 4040 class Monitor implements ActionListener { 4141 /* 重写ActionListener接口里面的actionPerformed(ActionEvent e)方法 */ 4242 public void actionPerformed(ActionEvent e) { 4343 System.out.println("A Button has been Pressed"); 4444 } 4545 }

复制代码

 测试代码二:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 public class TestActionEvent2{ 6 6 public static void main(String args[]){ 7 7 Frame f = new Frame("TestActionEvent"); 8 8 Button btn1 = new Button("start"); 9 9 Button btn2 = new Button("stop"); 1010 Monitor2 m2 = new Monitor2();//创建监听对象 1111 btn1.addActionListener(m2); 1212 /*一个监听对象同时监听两个按钮的动作*/ 1313 btn2.addActionListener(m2); 1414 btn2.setActionCommand("GameOver");//设置btn2的执行单击命令后的返回信息 1515 f.add(btn1,BorderLayout.NORTH); 1616 f.add(btn2,BorderLayout.CENTER); 1717 1818 f.pack(); 1919 f.setVisible(true); 2020 } 2121 } 2222 2323 class Monitor2 implements ActionListener{ 2424 public void actionPerformed(ActionEvent e){ 2525 System.out.println("a button has been pressed,"+"the relative info is:\n"+e.getActionCommand()); 2626 /*使用返回的监听对象e调用getActionCommand()方法获取两个按钮执行单击命令后的返回信息 2727 根据返回信息的不同区分开当前操作的是哪一个按钮,btn1没有使用setActionCommand()方法设置 2828 则btn1返回的信息就是按钮上显示的文本*/ 2929 } 3030 }

复制代码

二、TextField事件监听

测试代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 6 6 public class TestTextField { 7 7 public static void main(String args[]) { 8 8 new MyFrameTextField(); 9 9 } 1010 } 1111 1212 class MyFrameTextField extends Frame { 1313 MyFrameTextField() { 1414 TextField tf = new TextField(); 1515 add(tf); 1616 tf.addActionListener(new Monitor3()); 1717 tf.setEchoChar('*'); 1818 /* 1919 * 这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*, 2020 * 这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容 2121 */ 2222 setVisible(true); 2323 pack(); 2424 } 2525 } 2626 2727 class Monitor3 implements ActionListener { 2828 /* 2929 * 接口里面的所有方法都是public(公共的) 3030 * 所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上public 3131 */ 3232 public void actionPerformed(ActionEvent e) { 3333 /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */ 3434 TextField tf = (TextField) e.getSource(); 3535 /* 3636 * getSource()方法是拿到事件源,注意:拿到这个事件源的时候, 3737 * 是把它当作TextField的父类来对待 3838 * getSource()方法的定义是:“public Object getSource()”返回值是一个Object对象, 3939 * 所以要强制转换成TextField类型的对象 4040 * 在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法 4141 */ 4242 System.out.println(tf.getText());// tf.getText()是取得文本框里面的内容 4343 tf.setText("");// 把文本框里面的内容清空 4444 } 4545 }

复制代码

使用TextField类实现简单的计算器

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 6 6 public class TestMath { 7 7 public static void main(String args[]) { 8 8 new TFFrame(); 9 9 } 1010 } 1111 1212 /* 这里主要是完成计算器元素的布局 */ 1313 class TFFrame extends Frame { 1414 TFFrame() { 1515 /* 1616 * 创建3个文本框,并指定其初始大小分别为10个字符和15个字符的大小 这里使用的是TextField类的另外一种构造方法 public TextField(int columns) 1717 */ 1818 TextField num1 = new TextField(10); 1919 TextField num2 = new TextField(10); 2020 TextField num3 = new TextField(15); 2121 /* 创建等号按钮 */ 2222 Button btnEqual = new Button("="); 2323 btnEqual.addActionListener(new MyMonitor(num1, num2, num3)); 2424 /* 给等号按钮加上监听,让点击按钮后有响应事件发生 */ 2525 Label lblPlus = new Label("+"); 2626 /* “+”是一个静态文本,所以使用Label类创建一个静态文本对象 */ 2727 setLayout(new FlowLayout()); 2828 /* 把Frame默认的BorderLayout布局改成FlowLayout布局 */ 2929 add(num1); 3030 add(lblPlus); 3131 add(num2); 3232 add(btnEqual); 3333 add(num3); 3434 pack(); 3535 setVisible(true); 3636 3737 } 3838 } 3939 4040 class MyMonitor implements ActionListener { 4141 TextField num1, num2, num3; 4242 4343 /* 4444 * 为了使对按钮的监听能够对文本框也起作用, 4545 * 所以在自定义类MyMonitor里面定义三个TextField类型的对象 num1,num2,num3, 4646 * 并且定义了MyMonitor类的一个构造方法 这个构造方法带有三个TextField类型的参数, 4747 * 用于接收 从TFFrame类里面传递过来的三个TextField类型的参数 4848 * 然后把接收到的三个TextField类型的参数赋值给在本类中声明的 三个TextField类型的参数num1,num2,num3 然后再在actionPerformed()方法里面处理num1,num2,num3 4949 */ 5050 public MyMonitor(TextField num1, TextField num2, TextField num3) { 5151 this.num1 = num1; 5252 this.num2 = num2; 5353 this.num3 = num3; 5454 } 5555 5656 public void actionPerformed(ActionEvent e) { 5757 /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */ 5858 int n1 = Integer.parseInt(num1.getText());/* num1对象调用getText()方法取得自己显示的文本字符串 */ 5959 int n2 = Integer.parseInt(num2.getText());/* num2对象调用getText()方法取得自己显示的文本字符串 */ 6060 num3.setText("" + (n1 + n2));/* num3对象调用setText()方法设置自己的显示文本 */ 6161 num1.setText(""); 6262 /* 计算结束后清空num1,num2文本框里面的内容 */ 6363 num2.setText(""); 6464 // num3.setText(String.valueOf((n1+n2))); 6565 /* 字符串与任意类型的数据使用“+”连接时得到的一定是字符串, 6666 * 这里使用一个空字符串与int类型的数连接,这样就可以直接把(n1+n2)得到的int类型的数隐式地转换成字符串了, 6767 * 这是一种把别的基础数据类型转换成字符串的一个小技巧。 6868 * 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和转换成字符串 6969 */ 7070 } 7171 }

复制代码

JAVA里面的经典用法:在一个类里面持有另外一个类的引用

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 6 6 public class TestMath1 { 7 7 public static void main(String args[]) { 8 8 new TTMyFrame().launchFrame(); 9 9 /* 创建出TTMyFrame对象后调用lauchFrame()方法把计算器窗体显示出来 */ 1010 } 1111 } 1212 1313 /* 做好计算器的窗体界面 */ 1414 class TTMyFrame extends Frame { 1515 /* 把设计计算器窗体的代码封装成一个方法 */ 1616 TextField num1, num2, num3; 1717 1818 public void launchFrame() { 1919 num1 = new TextField(10); 2020 num2 = new TextField(15); 2121 num3 = new TextField(15); 2222 Label lblPlus = new Label("+"); 2323 Button btnEqual = new Button("="); 2424 btnEqual.addActionListener(new MyMonitorbtnEqual(this)); 2525 setLayout(new FlowLayout()); 2626 add(num1); 2727 add(lblPlus); 2828 add(num2); 2929 add(btnEqual); 3030 add(num3); 3131 pack(); 3232 setVisible(true); 3333 } 3434 } 3535 3636 /* 3737 * 这里通过取得TTMyFrame类的引用,然后使用这个引用去访问TTMyFrame类里面的成员变量 3838 * 这种做法比上一种直接去访问TTMyFrame类里面的成员变量要好得多, 3939 * 因为现在不需要知道 TTMyFrame类里面有哪些成员变量了, 4040 * 现在要访问TTMyFrame类里面的成员变量,直接使用 TTMyFrame类对象的引用去访问即可, 4141 * 这个TTMyFrame类的对象好比是一个大管家, 而我告诉大管家,我要访问TTMyFrame类里面的那些成员变量, 4242 * 大管家的引用就会去帮我找,不再需要我自己去找了。 4343 * 这种在一个类里面持有另一个类的引用的用法是一种非常典型的用法 4444 * 使用获取到的引用就可以在一个类里面访问另一个类的所有成员了 4545 */ 4646 class MyMonitorbtnEqual implements ActionListener { 4747 TTMyFrame ttmf = null; 4848 4949 public MyMonitorbtnEqual(TTMyFrame ttmf) { 5050 this.ttmf = ttmf; 5151 } 5252 5353 public void actionPerformed(ActionEvent e) { 5454 int n1 = Integer.parseInt(ttmf.num1.getText()); 5555 int n2 = Integer.parseInt(ttmf.num2.getText()); 5656 ttmf.num3.setText("" + (n1 + n2)); 5757 ttmf.num1.setText(""); 5858 ttmf.num2.setText(""); 5959 } 6060 }

复制代码

运行结果如下:

三、内部类

内部类的使用范例:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 6 6 public class TestMath3 { 7 7 8 8 public static void main(String args[]) { 9 9 new MyMathFrame().launchFrame(); 1010 } 1111 } 1212 1313 class MyMathFrame extends Frame { 1414 TextField num1, num2, num3; 1515 1616 public void launchFrame() { 1717 num1 = new TextField(10); 1818 num2 = new TextField(15); 1919 num3 = new TextField(15); 2020 Label lblPlus = new Label("+"); 2121 Button btnEqual = new Button("="); 2222 btnEqual.addActionListener(new MyMonitor()); 2323 setLayout(new FlowLayout()); 2424 add(num1); 2525 add(lblPlus); 2626 add(num2); 2727 add(btnEqual); 2828 add(num3); 2929 pack(); 3030 setVisible(true); 3131 } 3232 3333 /* 3434 * 这个MyMonitor类是内部类,它在MyFrame类里面定义 MyFrame类称为MyMonitor类的包装类 3535 */ 3636 /* 3737 * 使用内部类的好处: 3838 * 第一个巨大的好处就是可以畅通无阻地访问外部类(即内部类的包装类)的所有成员变量和方法 3939 * 如这里的在MyFrame类(外部类)定义的三个成员变量num1,num2,num3, 4040 * 在MyMonitor(内部类)里面就可以直接访问 4141 * 这相当于在创建外部类对象时内部类对象默认就拥有了一个外部类对象的引用 4242 */ 4343 private class MyMonitor implements ActionListener { 4444 public void actionPerformed(ActionEvent e) { 4545 int n1 = Integer.parseInt(num1.getText()); 4646 int n2 = Integer.parseInt(num2.getText()); 4747 num3.setText("" + (n1 + n2)); 4848 num1.setText(""); 4949 num2.setText(""); 5050 } 5151 } 5252 }

复制代码

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

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

四、Graphics 类

 测试代码:

复制代码

1 1 package cn.javastudy.summary; 2 2 3 3 import java.awt.*; 4 4 public class TestPaint{ 5 5 public static void main(String args[]){ 6 6 new MyPaint().launchFrame(); 7 7 /*在main()方法里面并没有显示调用paint(Graphics g)方法 8 8 可是当创建出Frame窗体后却可以看到Frame窗体上画出了 9 9 圆和矩形,这是因为paint()方法是一个比较特殊的方法 1010 在创建Frame窗体时会自动隐式调用 1111 当我们把Frame窗体最小化又再次打开时,又会再次调用 1212 paint()方法重新把圆和矩形在Frame窗体上画出来 1313     即每次需要重画Frame窗体的时候就会自动调用paint()方法*/ 1414 } 1515 } 1616 1717 class MyPaint extends Frame{ 1818 public void launchFrame(){ 1919 setBounds(200,200,640,480); 2020 setVisible(true); 2121 } 2222 2323 public void paint(Graphics g){ 2424 /*paint(Graphics g)方法有一个Graphics类型的参数g 2525 我们可以把这个g当作是一个画家,这个画家手里拿着一只画笔 2626 我们通过设置画笔的颜色与形状来画出我们想要的各种各样的图像*/ 2727 /*设置画笔的颜色*/ 2828 g.setColor(Color.red); 2929 g.fillOval(100,100,100,100);/*画一个实心椭圆*/ 3030 g.setColor(Color.green); 3131 g.fillRect(150,200,200,200);/*画一个实心矩形*/ 3232 /*这下面的两行代码是为了写程序的良好编程习惯而写的 3333 前面设置了画笔的颜色,现在就应该把画笔的初始颜色恢复过来 3434 就相当于是画家用完画笔之后把画笔上的颜色清理掉一样*/ 3535 Color c = g.getColor(); 3636 g.setColor(c); 3737 } 3838 }

复制代码

运行结果:

五、鼠标事件适配器

测试代码:

复制代码

1 1 package cn.galc.test; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 import java.util.*; 6 6 public class MyMouseAdapter{ 7 7 public static void main(String args[]) { 8 8 new MyFrame("drawing..."); 9 9 } 1010 } 1111 1212 class MyFrame extends Frame { 1313 ArrayList points = null; 1414 MyFrame(String s) { 1515 super(s); 1616 points = new ArrayList(); 1717 setLayout(null); 1818 setBounds(300,300,400,300); 1919 this.setBackground(new Color(204,204,255)); 2020 setVisible(true); 2121 this.addMouseListener(new Monitor()); 2222 } 2323 2424 public void paint(Graphics g) { 2525 Iterator i = points.iterator(); 2626 while(i.hasNext()){ 2727 Point p = (Point)i.next(); 2828 g.setColor(Color.BLUE); 2929 g.fillOval(p.x,p.y,10,10); 3030 3131 } 3232 } 3333 3434 public void addPoint(Point p){ 3535 points.add(p); 3636 } 3737 } 3838 3939 class Monitor extends MouseAdapter { 4040 public void mousePressed(MouseEvent e) { 4141 MyFrame f = (MyFrame)e.getSource(); 4242 f.addPoint(new Point(e.getX(),e.getY())); 4343 f.repaint(); 4444 } 4545 }

复制代码

六、window事件

 测试代码:

复制代码

1 1 package cn.galc.test; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 public class TestWindowClose{ 6 6 public static void main(String args[]){ 7 7 new WindowFrame("关闭WindowFrame"); 8 8 } 9 9 } 1010 1111 class WindowFrame extends Frame{ 1212 public WindowFrame(String s){ 1313 super(s); 1414 setBounds(200,200,400,300); 1515 setLayout(null); 1616 setBackground(new Color(204,204,255)); 1717 setVisible(true); 1818 this.addWindowListener(new WindowMonitor()); 1919 /*监听本窗体的动作,把所有的动作信息封装成一个对象传递到监听类里面*/ 2020 2121 this.addWindowListener( 2222 /*在一个方法里面定义一个类,这个类称为局部类,也叫匿名的内部类, 2323 这里的{……代码……}里面的代码很像一个类的类体,只不过这个类没有名字,所以叫匿名类 2424 在这里是把这个匿名类当成WindowAdapter类来使用,语法上这样写的本质意义是相当于这个匿名类 2525 从WindowAdapter类继承,现在new了一个匿名类的对象出来然后把这个对象当成WindowAdapter来使用 2626 这个匿名类出了()就没有人认识了*/ 2727 new WindowAdapter(){ 2828 public void windowClosing(WindowEvent e){ 2929 setVisible(false); 3030 System.exit(-1); 3131 } 3232 } 3333 ); 3434 } 3535 3636 /*这里也是将监听类定义为内部类*/ 3737 class WindowMonitor extends WindowAdapter{ 3838 /*WindowAdapter(Window适配器)类实现了WindowListener监听接口 3939 重写了WindowListener接口里面的所有方法 4040 如果直接使用自定义WindowMonitor类直接去 4141 实现WindowListener接口,那么就得要重写WindowListener接口 4242 里面的所有方法,但现在只需要用到这些方法里面的其中一个方法 4343 所以采用继承实现WindowListener监听接口的一个子类 4444 并重写这个子类里面需要用到的那个方法即可 4545 这种做法比直接实现WindowListener监听接口要重写很多个用不到的方法要简洁方便得多*/ 4646 /*重写需要用到的windowClosing(WindowEvent e)方法*/ 4747 public void windowClosing(WindowEvent e){ 4848 setVisible(false);/*将窗体设置为不显示,即可实现窗体关闭*/ 4949 System.exit(0);/*正常退出*/ 5050 } 5151 } 5252 }

复制代码

七、键盘响应事件——KeyEvent

测试代码:

复制代码

1 1 package cn.galc.test; 2 2 3 3 import java.awt.*; 4 4 import java.awt.event.*; 5 5 public class TestKeyEvent{ 6 6 public static void main(String args[]){ 7 7 new KeyFrame("键盘响应事件"); 8 8 } 9 9 } 1010 1111 class KeyFrame extends Frame{ 1212 public KeyFrame(String s){ 1313 super(s); 1414 setBounds(200,200,400,300); 1515 setLayout(null); 1616 setVisible(true); 1717 addKeyListener(new KeyMonitor()); 1818 } 1919 /*把自定义的键盘的监听类定义为内部类 2020 这个监听类从键盘适配器KeyAdapter类继承 2121 从KeyAdapter类继承也是为了可以简洁方便 2222 只需要重写需要用到的方法即可,这种做法比 2323 直接实现KeyListener接口要简单方便,如果 2424 直接实现KeyListener接口就要把KeyListener 2525 接口里面的所有方法重写一遍,但真正用到的 2626 只有一个方法,这样重写其他的方法但又用不到 2727 难免会做无用功*/ 2828 class KeyMonitor extends KeyAdapter{ 2929 public void keyPressed(KeyEvent e){ 3030 int keycode = e.getKeyCode(); 3131 /*使用getKeyCode()方法获取按键的虚拟码*/ 3232 /*如果获取到的键的虚拟码等于up键的虚拟码 3333 则表示当前按下的键是up键 3434 KeyEvent.VK_UP表示取得up键的虚拟码 3535 键盘中的每一个键都对应有一个虚拟码 3636 这些虚拟码在KeyEvent类里面都被定义为静态常量 3737 所以可以使用“类名.静态常量名”的形式访问得到这些静态常量*/ 3838 if(keycode == KeyEvent.VK_UP){ 3939 System.out.println("你按的是up键"); 4040 } 4141 } 4242 } 4343 } 4444 /*键盘的处理事件是这样的:每一个键都对应着一个虚拟的码, 4545 当按下某一个键时,系统就会去找这个键对应的虚拟的码,以此来确定当前按下的是那个键 4646 */

复制代码

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )