当前位置: 首页 > 编程笔记 >

java必学必会之GUI编程

黄骏喆
2023-03-14
本文向大家介绍java必学必会之GUI编程,包括了java必学必会之GUI编程的使用技巧和注意事项,需要的朋友参考一下

一、事件监听

测试代码一:

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;

public class TestTextField {
 public static void main(String args[]) {
  new MyFrameTextField();
 }
}

class MyFrameTextField extends Frame {
 MyFrameTextField() {
  TextField tf = new TextField();
  add(tf);
  tf.addActionListener(new Monitor3());
  tf.setEchoChar('*');
  /*
   * 这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*, 
   * 这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容
   */
  setVisible(true);
  pack();
 }
}

class Monitor3 implements ActionListener {
 /*
  * 接口里面的所有方法都是public(公共的) 
  * 所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上public
  */
 public void actionPerformed(ActionEvent e) {
  /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */
  TextField tf = (TextField) e.getSource();
  /*
   * getSource()方法是拿到事件源,注意:拿到这个事件源的时候,
   * 是把它当作TextField的父类来对待 
   * getSource()方法的定义是:“public Object getSource()”返回值是一个Object对象,
   * 所以要强制转换成TextField类型的对象 
   * 在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法
   */
  System.out.println(tf.getText());// tf.getText()是取得文本框里面的内容
  tf.setText("");// 把文本框里面的内容清空
 }
}

测试代码二:

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;
public class TestActionEvent2{
 public static void main(String args[]){
  Frame f = new Frame("TestActionEvent");
  Button btn1 = new Button("start");
  Button btn2 = new Button("stop");
  Monitor2 m2 = new Monitor2();//创建监听对象
  btn1.addActionListener(m2);
  /*一个监听对象同时监听两个按钮的动作*/
  btn2.addActionListener(m2);
  btn2.setActionCommand("GameOver");//设置btn2的执行单击命令后的返回信息
  f.add(btn1,BorderLayout.NORTH);
  f.add(btn2,BorderLayout.CENTER);
  
  f.pack();
  f.setVisible(true);
 }
}

class Monitor2 implements ActionListener{
 public void actionPerformed(ActionEvent e){
  System.out.println("a button has been pressed,"+"the relative info is:\n"+e.getActionCommand());
  /*使用返回的监听对象e调用getActionCommand()方法获取两个按钮执行单击命令后的返回信息
  根据返回信息的不同区分开当前操作的是哪一个按钮,btn1没有使用setActionCommand()方法设置
  则btn1返回的信息就是按钮上显示的文本*/
 }
}

二、TextField事件监听

测试代码:

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;

public class TestTextField {
 public static void main(String args[]) {
  new MyFrameTextField();
 }
}

class MyFrameTextField extends Frame {
 MyFrameTextField() {
  TextField tf = new TextField();
  add(tf);
  tf.addActionListener(new Monitor3());
  tf.setEchoChar('*');
  /*
   * 这个setEchoChar()方法是设置文本框输入时显示的字符,这里设置为*, 
   * 这样输入任何内容就都以*显示出来,不过打印出来时依然可以看到输入的内容
   */
  setVisible(true);
  pack();
 }
}

class Monitor3 implements ActionListener {
 /*
  * 接口里面的所有方法都是public(公共的) 
  * 所以从API文档复制void actionPerformed(ActionEvent e)时 要在void前面加上public
  */
 public void actionPerformed(ActionEvent e) {
  /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */
  TextField tf = (TextField) e.getSource();
  /*
   * getSource()方法是拿到事件源,注意:拿到这个事件源的时候,
   * 是把它当作TextField的父类来对待 
   * getSource()方法的定义是:“public Object getSource()”返回值是一个Object对象,
   * 所以要强制转换成TextField类型的对象 
   * 在一个类里面想访问另外一个类的事件源对象可以通过getSource()方法
   */
  System.out.println(tf.getText());// tf.getText()是取得文本框里面的内容
  tf.setText("");// 把文本框里面的内容清空
 }
}

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

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;

public class TestMath {
 public static void main(String args[]) {
  new TFFrame();
 }
}

/* 这里主要是完成计算器元素的布局 */
class TFFrame extends Frame {
 TFFrame() {
  /*
   * 创建3个文本框,并指定其初始大小分别为10个字符和15个字符的大小 这里使用的是TextField类的另外一种构造方法 public TextField(int columns)
   */
  TextField num1 = new TextField(10);
  TextField num2 = new TextField(10);
  TextField num3 = new TextField(15);
  /* 创建等号按钮 */
  Button btnEqual = new Button("=");
  btnEqual.addActionListener(new MyMonitor(num1, num2, num3));
  /* 给等号按钮加上监听,让点击按钮后有响应事件发生 */
  Label lblPlus = new Label("+");
  /* “+”是一个静态文本,所以使用Label类创建一个静态文本对象 */
  setLayout(new FlowLayout());
  /* 把Frame默认的BorderLayout布局改成FlowLayout布局 */
  add(num1);
  add(lblPlus);
  add(num2);
  add(btnEqual);
  add(num3);
  pack();
  setVisible(true);

 }
}

class MyMonitor implements ActionListener {
 TextField num1, num2, num3;

 /*
  * 为了使对按钮的监听能够对文本框也起作用, 
  * 所以在自定义类MyMonitor里面定义三个TextField类型的对象 num1,num2,num3,
  * 并且定义了MyMonitor类的一个构造方法 这个构造方法带有三个TextField类型的参数,
  * 用于接收 从TFFrame类里面传递过来的三个TextField类型的参数 
  * 然后把接收到的三个TextField类型的参数赋值给在本类中声明的 三个TextField类型的参数num1,num2,num3 然后再在actionPerformed()方法里面处理num1,num2,num3
  */
 public MyMonitor(TextField num1, TextField num2, TextField num3) {
  this.num1 = num1;
  this.num2 = num2;
  this.num3 = num3;
 }

 public void actionPerformed(ActionEvent e) {
  /* 事件的相关信息都封装在了对象e里面,通过对象e的相关方法就可以获取事件的相关信息 */
  int n1 = Integer.parseInt(num1.getText());/* num1对象调用getText()方法取得自己显示的文本字符串 */
  int n2 = Integer.parseInt(num2.getText());/* num2对象调用getText()方法取得自己显示的文本字符串 */
  num3.setText("" + (n1 + n2));/* num3对象调用setText()方法设置自己的显示文本 */
  num1.setText("");
  /* 计算结束后清空num1,num2文本框里面的内容 */
  num2.setText("");
  // num3.setText(String.valueOf((n1+n2)));
  /* 字符串与任意类型的数据使用“+”连接时得到的一定是字符串,
   * 这里使用一个空字符串与int类型的数连接,这样就可以直接把(n1+n2)得到的int类型的数隐式地转换成字符串了,
   * 这是一种把别的基础数据类型转换成字符串的一个小技巧。
   * 也可以使用“String.valueOf((n1+n2))”把(n1+n2)的和转换成字符串 
   */
 }
}

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

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;

public class TestMath1 {
 public static void main(String args[]) {
  new TTMyFrame().launchFrame();
  /* 创建出TTMyFrame对象后调用lauchFrame()方法把计算器窗体显示出来 */
 }
}

/* 做好计算器的窗体界面 */
class TTMyFrame extends Frame {
 /* 把设计计算器窗体的代码封装成一个方法 */
 TextField num1, num2, num3;

 public void launchFrame() {
  num1 = new TextField(10);
  num2 = new TextField(15);
  num3 = new TextField(15);
  Label lblPlus = new Label("+");
  Button btnEqual = new Button("=");
  btnEqual.addActionListener(new MyMonitorbtnEqual(this));
  setLayout(new FlowLayout());
  add(num1);
  add(lblPlus);
  add(num2);
  add(btnEqual);
  add(num3);
  pack();
  setVisible(true);
 }
}

/*
 * 这里通过取得TTMyFrame类的引用,然后使用这个引用去访问TTMyFrame类里面的成员变量 
 * 这种做法比上一种直接去访问TTMyFrame类里面的成员变量要好得多,
 * 因为现在不需要知道 TTMyFrame类里面有哪些成员变量了,
 * 现在要访问TTMyFrame类里面的成员变量,直接使用 TTMyFrame类对象的引用去访问即可,
 * 这个TTMyFrame类的对象好比是一个大管家, 而我告诉大管家,我要访问TTMyFrame类里面的那些成员变量,
 * 大管家的引用就会去帮我找,不再需要我自己去找了。 
 * 这种在一个类里面持有另一个类的引用的用法是一种非常典型的用法 
 * 使用获取到的引用就可以在一个类里面访问另一个类的所有成员了
 */
class MyMonitorbtnEqual implements ActionListener {
 TTMyFrame ttmf = null;

 public MyMonitorbtnEqual(TTMyFrame ttmf) {
  this.ttmf = ttmf;
 }

 public void actionPerformed(ActionEvent e) {
  int n1 = Integer.parseInt(ttmf.num1.getText());
  int n2 = Integer.parseInt(ttmf.num2.getText());
  ttmf.num3.setText("" + (n1 + n2));
  ttmf.num1.setText("");
  ttmf.num2.setText("");
 }
}

运行结果如下:

三、内部类

内部类的使用范例:

package cn.javastudy.summary;

import java.awt.*;
import java.awt.event.*;

public class TestMath3 {

 public static void main(String args[]) {
  new MyMathFrame().launchFrame();
 }
}

class MyMathFrame extends Frame {
 TextField num1, num2, num3;

 public void launchFrame() {
  num1 = new TextField(10);
  num2 = new TextField(15);
  num3 = new TextField(15);
  Label lblPlus = new Label("+");
  Button btnEqual = new Button("=");
  btnEqual.addActionListener(new MyMonitor());
  setLayout(new FlowLayout());
  add(num1);
  add(lblPlus);
  add(num2);
  add(btnEqual);
  add(num3);
  pack();
  setVisible(true);
 }

 /*
  * 这个MyMonitor类是内部类,它在MyFrame类里面定义 MyFrame类称为MyMonitor类的包装类
  */
 /*
  * 使用内部类的好处: 
  * 第一个巨大的好处就是可以畅通无阻地访问外部类(即内部类的包装类)的所有成员变量和方法 
  * 如这里的在MyFrame类(外部类)定义的三个成员变量num1,num2,num3, 
  * 在MyMonitor(内部类)里面就可以直接访问 
  * 这相当于在创建外部类对象时内部类对象默认就拥有了一个外部类对象的引用
  */
 private class MyMonitor implements ActionListener {
  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("");
  }
 }
}

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

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

四、Graphics 类

测试代码:

package cn.javastudy.summary;

import java.awt.*;
public class TestPaint{
 public static void main(String args[]){
  new MyPaint().launchFrame();
  /*在main()方法里面并没有显示调用paint(Graphics g)方法
  可是当创建出Frame窗体后却可以看到Frame窗体上画出了
  圆和矩形,这是因为paint()方法是一个比较特殊的方法
  在创建Frame窗体时会自动隐式调用
  当我们把Frame窗体最小化又再次打开时,又会再次调用
  paint()方法重新把圆和矩形在Frame窗体上画出来
    即每次需要重画Frame窗体的时候就会自动调用paint()方法*/
 }
}

class MyPaint extends Frame{
 public void launchFrame(){
  setBounds(200,200,640,480);
  setVisible(true);
 }
 
 public void paint(Graphics g){
  /*paint(Graphics g)方法有一个Graphics类型的参数g
  我们可以把这个g当作是一个画家,这个画家手里拿着一只画笔
  我们通过设置画笔的颜色与形状来画出我们想要的各种各样的图像*/
  /*设置画笔的颜色*/
  g.setColor(Color.red);
  g.fillOval(100,100,100,100);/*画一个实心椭圆*/
  g.setColor(Color.green);
  g.fillRect(150,200,200,200);/*画一个实心矩形*/
  /*这下面的两行代码是为了写程序的良好编程习惯而写的
  前面设置了画笔的颜色,现在就应该把画笔的初始颜色恢复过来
  就相当于是画家用完画笔之后把画笔上的颜色清理掉一样*/
  Color c = g.getColor();
  g.setColor(c);
 }
}

运行结果:

五、鼠标事件适配器

测试代码:

package cn.galc.test;

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class MyMouseAdapter{
 public static void main(String args[]) {
 new MyFrame("drawing...");
 }
}

class MyFrame extends Frame {
 ArrayList points = null;
 MyFrame(String s) {
 super(s);
 points = new ArrayList(); 
 setLayout(null);
 setBounds(300,300,400,300); 
 this.setBackground(new Color(204,204,255));
 setVisible(true);
 this.addMouseListener(new Monitor());
 }
 
 public void paint(Graphics g) {
 Iterator i = points.iterator();
 while(i.hasNext()){
  Point p = (Point)i.next();
  g.setColor(Color.BLUE);
  g.fillOval(p.x,p.y,10,10);
  
 }
 }
 
 public void addPoint(Point p){
 points.add(p);
 }
}

class Monitor extends MouseAdapter {
 public void mousePressed(MouseEvent e) {
 MyFrame f = (MyFrame)e.getSource();
 f.addPoint(new Point(e.getX(),e.getY()));
 f.repaint();
 }
}

六、window事件

测试代码:

package cn.galc.test;

import java.awt.*;
import java.awt.event.*;
public class TestWindowClose{
 public static void main(String args[]){
 new WindowFrame("关闭WindowFrame");
 }
}

class WindowFrame extends Frame{
 public WindowFrame(String s){
 super(s);
 setBounds(200,200,400,300);
 setLayout(null);
 setBackground(new Color(204,204,255));
 setVisible(true);
 this.addWindowListener(new WindowMonitor());
/*监听本窗体的动作,把所有的动作信息封装成一个对象传递到监听类里面*/
 
 this.addWindowListener(
 /*在一个方法里面定义一个类,这个类称为局部类,也叫匿名的内部类,
 这里的{……代码……}里面的代码很像一个类的类体,只不过这个类没有名字,所以叫匿名类
 在这里是把这个匿名类当成WindowAdapter类来使用,语法上这样写的本质意义是相当于这个匿名类
 从WindowAdapter类继承,现在new了一个匿名类的对象出来然后把这个对象当成WindowAdapter来使用
 这个匿名类出了()就没有人认识了*/
  new WindowAdapter(){
  public void windowClosing(WindowEvent e){
   setVisible(false);
   System.exit(-1);
  }
  }
 );
 }
 
 /*这里也是将监听类定义为内部类*/
 class WindowMonitor extends WindowAdapter{
 /*WindowAdapter(Window适配器)类实现了WindowListener监听接口
 重写了WindowListener接口里面的所有方法
 如果直接使用自定义WindowMonitor类直接去
 实现WindowListener接口,那么就得要重写WindowListener接口
 里面的所有方法,但现在只需要用到这些方法里面的其中一个方法
 所以采用继承实现WindowListener监听接口的一个子类
 并重写这个子类里面需要用到的那个方法即可
 这种做法比直接实现WindowListener监听接口要重写很多个用不到的方法要简洁方便得多*/
/*重写需要用到的windowClosing(WindowEvent e)方法*/
 public void windowClosing(WindowEvent e){
  setVisible(false);/*将窗体设置为不显示,即可实现窗体关闭*/
  System.exit(0);/*正常退出*/
  }
 }
}

七、键盘响应事件——KeyEvent

测试代码:

package cn.galc.test;

import java.awt.*;
import java.awt.event.*;
public class TestKeyEvent{
 public static void main(String args[]){
 new KeyFrame("键盘响应事件");
 }
}

class KeyFrame extends Frame{
 public KeyFrame(String s){
  super(s);
  setBounds(200,200,400,300);
  setLayout(null);
  setVisible(true);
  addKeyListener(new KeyMonitor());
 }
 /*把自定义的键盘的监听类定义为内部类
 这个监听类从键盘适配器KeyAdapter类继承
 从KeyAdapter类继承也是为了可以简洁方便
 只需要重写需要用到的方法即可,这种做法比
 直接实现KeyListener接口要简单方便,如果
 直接实现KeyListener接口就要把KeyListener
 接口里面的所有方法重写一遍,但真正用到的
 只有一个方法,这样重写其他的方法但又用不到
 难免会做无用功*/ 
 class KeyMonitor extends KeyAdapter{
 public void keyPressed(KeyEvent e){
  int keycode = e.getKeyCode();
  /*使用getKeyCode()方法获取按键的虚拟码*/
  /*如果获取到的键的虚拟码等于up键的虚拟码
  则表示当前按下的键是up键
  KeyEvent.VK_UP表示取得up键的虚拟码
  键盘中的每一个键都对应有一个虚拟码
  这些虚拟码在KeyEvent类里面都被定义为静态常量
  所以可以使用“类名.静态常量名”的形式访问得到这些静态常量*/
  if(keycode == KeyEvent.VK_UP){
   System.out.println("你按的是up键");
   }
  }
 }
}
/*键盘的处理事件是这样的:每一个键都对应着一个虚拟的码,
当按下某一个键时,系统就会去找这个键对应的虚拟的码,以此来确定当前按下的是那个键
*/

通过这篇文章和大家一起学习了GUI编程,希望大家对GUI编程有了更全面的认识,关于GUI编程远不止这些,还需要大家继续学习。

 类似资料:
  • 本文向大家介绍java必学必会之网络编程,包括了java必学必会之网络编程的使用技巧和注意事项,需要的朋友参考一下 一、网络基础概念   首先理清一个概念:网络编程 != 网站编程,网络编程现在一般称为TCP/IP编程。    二、网络通信协议及接口    三、通信协议分层思想    四、参考模型    五、IP协议      每个人的电脑都有一个独一无二的IP地址,这样互相通信时就不会传错信息了

  • 本文向大家介绍java必学必会之线程(1),包括了java必学必会之线程(1)的使用技巧和注意事项,需要的朋友参考一下 一、线程的基本概念    线程理解:线程是一个程序里面不同的执行路径   每一个分支都叫做一个线程,main()叫做主分支,也叫主线程。   程只是一个静态的概念,机器上的一个.class文件,机器上的一个.exe文件,这个叫做一个进程。程序的执行过程都是这样的:首先把程序的代码

  • 本文向大家介绍java必学必会之线程(2),包括了java必学必会之线程(2)的使用技巧和注意事项,需要的朋友参考一下 一、线程的优先级别    线程优先级别的使用范例: 二、线程同步    synchronized关键字的使用范例: 线程死锁的问题:   解决线程死锁的问题最好只锁定一个对象,不要同时锁定两个对象 生产者消费者问题: 以上就是关于java线程的全部内容介绍,大家可以结合第一篇《j

  • 本文向大家介绍php编程每天必学之验证码,包括了php编程每天必学之验证码的使用技巧和注意事项,需要的朋友参考一下 本文为大家分享了php图片验证码的实现代码,分享给大家供大家参考,具体内容如下 1.验证码图片生成 captcha.php 2.页面实现验证码功能 form.php 以上就是本文的全部内容,帮助大家轻松实现php图片验证码。

  • 本文向大家介绍Bootstrap每天必学之表单,包括了Bootstrap每天必学之表单的使用技巧和注意事项,需要的朋友参考一下 本文主要讲解的是表单,这个其实对于做过网站的人来说,并不陌生,而且可以说是最为常用的提交数据的Form表单。本文主要来讲解一下内容: 1.基本案例 2.内联表单 3.水平排列的表单 4.被支持的控件 5.静态控件 6.控件状态 7.控件尺寸 8.帮助文本 基本案例  单独

  • 本文向大家介绍Bootstrap每天必学之折叠,包括了Bootstrap每天必学之折叠的使用技巧和注意事项,需要的朋友参考一下 本文主要来学习一下JavaScript插件--折叠。 1、过渡效果 关于过渡效果 对于简单的过渡效果,只需将transition.js和其它JS文件一起引入即可。如果你使用的是编译(或压缩)好的bootstrap.js文件,就无需再单独将其引入了。 What's insi