1. [Java] MouseListener、MouseMotionListener 监听器与 MouseEvent 事件

1. 监听器 - MouseListener(鼠标监听器)

addMouseListener() 添加、 removeMouseListener() 移除此监听器对象;这两个方法都是在 JComponent 类中定义的,因此此监听器适用于 JComponent 及其派生类。
MouseListener 监听器是监听鼠标对组件进行的操作的,共有以下 5 5 5 个方法:

public void mouseClicked(MouseEvent e);	//鼠标点击(左、中、右键和单、双击均可触发)
public void mousePressed(MouseEvent e);	//鼠标按下(左、中、右键均可触发)
public void mouseReleased(MouseEvent e);//鼠标松开

public void mouseEntered(MouseEvent e);	//鼠标浮动
public void mouseExited(MouseEvent e);	//鼠标离开

“鼠标浮动”指的是鼠标移动到组件上没有点击的时候,严肃点应该叫“进入”,但我个人感觉“浮动”更有趣。

每当鼠标进行完整的点击时,都会依次触发以下事件:

鼠标按下
鼠标松开
NULL
mousePressed()
mouseReleased()
mouseClicked()

需要注意的一点是,鼠标事件严格按照上面的流程图触发

例如,如果在 mousePressed 之后没有触发 mouseReleased(鼠标按下后拖到别处再松开),则也不会有接下来的 mouseClicked;
或是没有 mousePressed 空有 “mouseReleased”(鼠标在别处按下拖到此组件中再松开),则不会触发上述流程图中的任何事件。

可以简单地记住:上面流程图中的任何事件都依赖于它左侧的事件

2. 监听器 - MouseMotionListener(鼠标运动监听器)

此监听器同样适用于 JComponent 及其派生类。
尽管 MouseMotionListener 也是个监听器,但 JavaSwing 并没有提供“MouseMotionEvent”这样的事件,所以 MouseListener 和 MouseMotionListener 都是用的 MouseEvent 事件。

public void mouseMoved(MouseEvent e);	//鼠标移动
public void mouseDragged(MouseEvent e);	//鼠标拖动

这里的“鼠标移动”是狭义的,也就是说它并不包含“鼠标拖动”,因此这两个事件是“互斥”的。

3. 事件 - MouseEvent(鼠标事件)

链接:JDK 文档

没找到想看内容或没看懂的戳这里:

  • JDK17 在线文档(可以把路径中的 17 17 17 改为自己的版本,但需大于等于 11 11 11
  • 离线文档下载:JDK17JDK8(可以把路径中的 17 17 17 8 8 8 改为自己的版本)

3.1 getXOnScreen()、getYOnScreen()、getLocationOnScreen()

“绝对坐标”指相对于整个电脑屏幕的坐标,从左上角开始。

public int getXOnScreen(); //返回鼠标指针的绝对 X 坐标
public int getYOnScreen(); //返回鼠标指针的绝对 Y 坐标
public Point getLocationOnScreen(); //返回鼠标指针的绝对坐标

其中的 getLocationOnScreen() 方法返回 java.awt.Point 类型,定义如下:

public int x, y;

注意它们既没有被 final 关键字修饰,也没有 synchronized 的 Getter、Setter 方法,因此 Point 类是可变的。(也许是它的设计初衷仅打算在 JavaSwing 中使用,而后者广泛地使用线程封闭技术)

3.1.1 示例:输出鼠标指针的绝对坐标

log.info( e.getLocationOnScreen() );
//Logger 一般会自动调用 Point 类的 toString 方法。

out.printf( "(%d, %d)\n", e.getXOnScreen(), e.getYOnScreen() );
//用 printf 格式化,推荐方式。

3.2 getX()、getY()、getPoint()

public int getX(); //返回鼠标指针的相对 X 坐标
public int getY(); //返回鼠标指针的相对 Y 坐标
public java.awt.Point getPoint(); //返回鼠标指针的相对坐标

用法及示例同上一节。这一节与上一节的区别在于,上一节是绝对坐标(相对于整个屏幕),这一节则是相对于 this 组件的坐标。

3.3 getClickCount()

仅用于点击事件:

public int getClickCount(); //返回点击的次数(不局限于 1~2)

按下不同键不构成双击。例如,按顺序快速点击左键与右键,则两次都返回 1 1 1
如果是在没有鼠标点击的事件中调用此方法(mouseEntered 等),则返回 0 0 0
注意,此方法的返回值并不局限于 0 0 0 1 1 1 2 2 2,如果连续点击 3 3 3 次,则 getClickCount() 就为 3 3 3

3.4 getButton()

用于鼠标按下、松开和点击事件:

public int getButton(); //返回触发事件的鼠标按钮(常量)

//鼠标按钮常量(位于 MouseEvent 中):
public static final int NOBUTTON = 0;	//没有按下鼠标按键(例如 mouseEntered 等事件)
public static final int BUTTON1 = 1;	//鼠标左键
public static final int BUTTON2 = 2;	//鼠标中键
public static final int BUTTON3 = 3;	//鼠标右键

鼠标中键其实就是按下滚轮(打游戏的各位肯定都懂)。

如果你的鼠标有三个以上的按钮,则在 MouseEvent 中找不到对应的常量。比如你的鼠标有 5 5 5 个按钮,则可能返回以下数值:

数值对应常量鼠标按键
0 0 0 j a v a . a w t . e v e n t . M o u s e E v e n t . N O B U T T O N \mathsf{java.awt.event.MouseEvent.NOBUTTON} java.awt.event.MouseEvent.NOBUTTON(无)
1 1 1 j a v a . a w t . e v e n t . M o u s e E v e n t . B U T T O N 1 \mathsf{java.awt.event.MouseEvent.BUTTON1} java.awt.event.MouseEvent.BUTTON1左键
2 2 2 j a v a . a w t . e v e n t . M o u s e E v e n t . B U T T O N 2 \mathsf{java.awt.event.MouseEvent.BUTTON2} java.awt.event.MouseEvent.BUTTON2中键
3 3 3 j a v a . a w t . e v e n t . M o u s e E v e n t . B U T T O N 3 \mathsf{java.awt.event.MouseEvent.BUTTON3} java.awt.event.MouseEvent.BUTTON3右键
4 4 4(无)(第 4 4 4 个按键)
5 5 5(无)(第 5 5 5 个按键)

3.4.1 示例:检测按下的是什么键

用 If-else 语句:

if (e.getButton() == MonseEvent.BUTTON1)
	return "鼠标左键";
else if (e.getButton() == MonseEvent.BUTTON2)
	return "鼠标中键";
else if (e.getButton() == MonseEvent.BUTTON3)
	return "鼠标右键";
else
	return "按键 " + e.getButton();

或是用 Switch 语句:

switch ( e.getButton() ) {
	case MouseEvent.BUTTON1:
		return "鼠标左键";
	case MouseEvent.BUTTON2:
		return "鼠标中键";
	case MouseEvent.BUTTON3:
		return "鼠标右键";
	default:
		return "按键 " + e.getButton();
}

3.5 getWhen()

顾名思义,作用为返回事件所发生的时间,是 UTC(协调世界时)时间。

public long getWhen();
//返回事件发生时的时间戳(1970 年 1 月 1 日 00:00 至今的毫秒数)

3.5.1 示例:输出事件发生时间(不同格式)

由于 getWhen() 所返回的是 1970 年至今的毫秒数,一般需要经过处理再打印出来,所以平时可以用 java.util.Date 类进行快捷地处理,如果需要还可以用 SimpleDateFormat 类进行可定制的处理:

import java.util.Date;
import java.text.SimpleDateFormat;

log.info( e.getWhen() );
//直接打印未经处理的毫秒数,如:“1675421707077”

//使用 Date 类:
log.info( new Date(e.getWhen()) );
//大多数 Logger 会自动调用 Date 类的 toString() 方法
//如:“Fri Feb 03 18:55:07 CST 2023”

//使用 SimpleDateFormat 进行可定制的格式化:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info( sdf.format(e.getWhen()) ); //如:“2023-02-03 18:55:07”

//使用 printf() 方法:
out.printf("%tc", e.getWhen()); //如:“周五 2月 03 18:55:07 CST 2023”

如你所见,还可以用 printf() 方法,只要使用时间占位符 %t。范例中的 c 表示格式化方式,可以替换为其他方式。

3.6 paramString()

返回标识此事件的参数字符串,此方法对于事件日志记录和调试很有用。

示例输出:

MOUSE_PRESSED,(52,93),absolute(59,163),button=1,modifiers=Ctrl+Button1,extModifiers=Ctrl,clickCount=2

输出介绍:

  1. “MOUSE_PRESSED”,触发的事件类型。范例是在 mousePressed 事件中调用。详情见 3.9 节。
  2. “(52,93)”,触发事件时鼠标相对于此组件的坐标。格式“(X,Y)”。和上文 3.2 中介绍的方法作用相同。
  3. “absolute(59,163)”,触发事件时鼠标的绝对坐标,前面跟一个“absolute”单词。与上文 3.1 中介绍的方法作用相同。
  4. “button=1”,指触发事件所用的鼠标按钮是哪个,示例中为左键。与上文 3.4 介绍的 getButton() 返回的值相同。
  5. “modifiers=Ctrl+Button1”,指触发事件时的修饰符。与接下来将在 3.7 介绍的方法作用相同。
  6. “extModifiers=Ctrl”,指触发事件时的修饰符。详情请见 3.8 节。
  7. “clickCount=2”,指点击次数,与上文 3.3 中介绍的方法作用相同。

……如有遗漏欢迎补充。

3.7 getModifiers()、getMouseModifiersText()

其实 getModifiers() 方法已被打上 Deprecated 注解,不提倡使用。更提倡用下一节介绍的 getModifiersEx() 方法,但上文有所提及,所以简单介绍一下。
getModifiers() 方法返回事件的修饰符,常量在 InputEvent 中定义,用位或方式结合。如我按住 Ctrl 键用左键触发事件,返回的修饰符如下:

e.getModifiers() == InputEvent.CTRL_MASK | InputEvent.BUTTON1_MASK;

之所以被废除,个人猜测是因为有时有些奇怪的 BUG(也许和跨平台有关):

//如我按下鼠标中键,它返回这个:
InputEvent.ALT_MASK | InputEvent.BUTTON2_MASK //可实际上我并没有按 Alt

再说说静态方法 getMouseModifiersText() :

public static String getMouseModifiersText(int modifiers);
//将 getModifiers() 返回的修饰符翻译成字符串

//比如这个:
InputEvent.CTRL_MASK | InputEvent.BUTTON1_MASK
//它翻译为:
"Ctrl+Button1" //(实际上没有双引号)

3.8 getModifiersEx()、getModifiersExText()

静态方法 getModifiersExText() 在 InputEvent 类中定义。
上一节中 getModifiers() 和 getMouseModifiersText() 的合适替代品,更提倡用这个。
上一节所使用的常量为 XXX_MASK,这节所介绍的方法所使用的常量为 XXX_DOWN_MASK

getModifiersEx() 同样有一些奇怪的 BUG(特性?),我把它分为 2 2 2 种情况(在我的台式机上测试):

一、BUG(特性?) 发作,不仅是上一节中介绍的凭空多出按键,而且附赠忽略鼠标按钮,还是上一节中的范例:

//我按下鼠标中键:
InputEvent.BUTTON2_DOWN_MASK //我认为它应该返回这个
InputEvent.ALT_DOWN_MASK //结果事实让我震惊了
//(它先生成了一个 Alt,然后又把 Button2 给忽略掉了)

二、奇奇怪怪的修饰符也不加了,按钮也不忽略了,按下哪个就返回哪个。总之就突然恢复正常了,如:

//我按下 Ctrl + Alt + 左键,它正常返回:
InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK | InputEvent.BUTTON1_DOWN_MASK

就挺玄学的,我在不同事件中测试,结果如下:

监听器事件状态
MouseListenermousePressed正常返回
MouseListenermouseReleased离谱特性
MouseListenermouseClicked离谱特性
MouseMotionListenermouseDragged正常返回

其他事件则没有监听鼠标点击。

至于 getModifiersExText() 则和上一节中的 getMouseModifiers() 作用相同。但 getModifiersExText() 用的是 XXX_DOWN_MASK,getModifiersText() 用的 XXX_MASK,所以不能混起来用。上一节中的两个方法配套使用,这一节的两个方法也只能配套使用。

3.9 getID()

返回触发的事件(int 常量),用于编写静态方法(工具)时使用,可用的常量如下:

常量名称事件
MOUSE_PRESSEDmousePressed(鼠标按下)501
MOUSE_RELEASEDmouseReleased(鼠标松开)502
MOUSE_CLICKEDmouseClicked(鼠标点击)500
MOUSE_ENTEREDmouseEntered(鼠标浮动)504
MOUSE_EXITEDmouseExited(鼠标离开)505
MOUSE_MOVEDmouseMoved(鼠标移动)503
MOUSE_DRAGGEDmouseDragged(鼠标拖动)506

还有一个较为特殊,这个是属于 MouseWheelListener(鼠标滚轮监听器)的:

常量名称事件
MOUSE_WHEELmouseWheelMoved(鼠标滚轮滚动)507

3.9.1 示例:id --> 字符串

由于常量的值是 int 类型,要转化为字符串,可以用 Switch 或 If-else 暴力检测,也可以用反射获取常量名。反正 Switch、If-else 就是疯狂复制粘贴,这里就贴一个简短的反射代码吧:

public static String getEventName(final int id)
		throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
	Class<?> c = MouseWheelEvent.class; //MouseWheelEvent 包含上表中所有常量
	Field first = c.getField("MOUSE_FIRST"), last = c.getField("MOUSE_LAST"); //跟 MouseEvent 类库的一些设计有关

	if (first.getInt(null) <= id && id <= last.getInt(null)) //常量是否存在
		for (Field field : c.getFields())
			if (field.get(null) instanceof Integer
					&& field.getInt(null) == id //如果检测到了 int 常量且值相等
					&& !field.equals(first) && !field.equals(last))
				return field.getName();
	throw new IllegalArgumentException("The id doesn't exist.");
}

/****** 关于上面的 first 和 last: ******/

//In MouseEvent.class:
public static final int MOUSE_FIRST	= 501; //注意,和 MOUSE_PRESSED 的值相等
public static final int MOUSE_LAST	= 507; //和 MOUSE_WHEEL_MOVED 的值相等

3.10 getSource()

此方法返回触发事件的对象,返回类型为 Object,所以需要进行显式的向下转型。

public Object getSource(); //返回触发事件的对象

常用于不同按钮添加同一个监听器对象,还有自己的静态方法(工具)中使用。

3.10.1 示例:输出点击的按钮名称

就是上面说的不同按钮添加同一个监听器对象:

public static void main(String[] args) {
	MouseListener ml = new MouseAdapter() {
		//由于只实现了一个 mouseClicked 方法,使用将在第 5.1 节中介绍的鼠标适配器
		@Override
		public void mouseClicked(MouseEvent e) {
			JButton source = (JButton) e.getSource(); //获取触发的按钮对象
			System.out.printf(
					"Clicked button: \"%s\".\n", source.getText() ); //输出按钮名
		}
	};

	//测试代码:
	JButton button1 = new JButton("Button-1"),
			button2 = new JButton("Button-2");
	button1.addMouseListener(ml); //添加同一个监听器
	button2.addMouseListener(ml);

	JFrame frame = new JFrame("示例-3.10.1");
	frame.setSize(240, 180);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setLayout(new GridLayout(1, 2)); //这里用网格布局管理器
	frame.add(button1);
	frame.add(button2);
	frame.setVisible(true);
}

4. 示例

4.1 实时显示鼠标坐标

显示鼠标相对于 JFrame 窗口的坐标。
这是 MouseMotionListener 监听器的示例:

public static void main(String[] args) {
	JFrame frame = new JFrame("示例-4.1");
	JLabel label = new JLabel(); //显示鼠标坐标
	frame.addMouseMotionListener(new MouseMotionListener() {
		public void mouseMoved(MouseEvent e) {
			label.setText(String.format(
					"X=%d, Y=%d", e.getX(), e.getY()
			)); }
		public void mouseDragged(MouseEvent e) {
			label.setText(String.format(
					"X=%d, Y=%d", e.getX(), e.getY()
			)); }
	});

	//测试代码:
	frame.setSize(240, 180);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.add(label);
	frame.setVisible(true);
}

4.2 生成简单日志字符串

没有太大实用意义,但运用了第 3 3 3 节中大部分方法。

/**
 * 根据参数生成一个简单的代表日志的字符串。
 * 字符串格式:[时间]_触发事件,鼠标坐标,绝对坐标,鼠标按钮,修饰符,修饰符新,点击次数。
 *
 * @param e 鼠标事件的对象,包含很多重要信息
 * @return 生成的一行代表日志的字符串
 */
private static String log(MouseEvent e) throws IllegalAccessException {
	return String.format(
		"[%s]_id=%s, coordinate=[%d,%d], absolute[%d,%d], button=%d, modifiers=%s, modifiersEx=%s, clickCount=%d",
			new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss").format(e.getWhen()), //事件发生时间
			e.getID(), //发生的事件
			e.getX(), e.getY(), //事件发生时鼠标的相对坐标
			e.getXOnScreen(), e.getYOnScreen(), //鼠标的绝对坐标
			e.getButton(), //按下的鼠标按钮
			MouseEvent.getMouseModifiersText(e.getModifiers()), //修饰符
			InputEvent.getModifiersExText(e.getModifiersEx()), //新修饰符
			e.getClickCount() //点击次数
		);
}

现在可以把此方法加入到监听器中试一试了:

public static void main(String[] args) {
	JButton button = new JButton("Button");
	button.addMouseListener(new MouseListener() {
		public void mousePressed(MouseEvent e) { System.out.println(log(e)); }
		public void mouseReleased(MouseEvent e) { System.out.println(log(e)); }
		public void mouseClicked(MouseEvent e) { System.out.println(log(e)); }
		public void mouseEntered(MouseEvent e) { System.out.println(log(e)); }
		public void mouseExited(MouseEvent e) { System.out.println(log(e)); }
	});
	button.addMouseMotionListener(new MouseMotionListener() {
		public void mouseMoved	(MouseEvent e) { System.out.println(log(e)); }
		public void mouseExited	(MouseEvent e) { System.out.println(log(e)); }
	});

	JFrame frame = new JFrame("示例-4.2");
	frame.setSize(240, 180);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.add(button);
	frame.setVisible(true);
}

4.3 鼠标拖动 JLabel

利用 MouseMotionListener,在鼠标拖动时让 JLabel 的坐标保持和鼠标偏移量同步,效果很不错。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

@SuppressWarnings("serial")
public class DemoFrame extends JFrame {

	private Point mousePos; //用于计算偏移量(now - mousePos)
	private JLabel label = new JLabel("JLabel", JLabel.CENTER);

	public DemoFrame(String title, int width, int height) {
		this.setTitle(title);
		this.setSize(width, height);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setLayout(null); //默认布局管理器,直接控制坐标
		this.add(label);

		label.setSize(width / 8, height / 8);
		label.setBorder(BorderFactory.createLineBorder(Color.BLACK)); //设置黑色边框,便于拖动观察
		label.addMouseMotionListener(new MouseMotionListener() {
			@Override
			public void mouseMoved(MouseEvent e) //实时记录鼠标坐标
				{ mousePos = e.getLocationOnScreen(); }

			@Override
			public void mouseDragged(MouseEvent e) {
				Point offset = new Point(e.getXOnScreen() - mousePos.x, e.getYOnScreen() - mousePos.y); //计算鼠标坐标偏移量
				label.setBounds(label.getX() + offset.x, label.getY() + offset.y, label.getWidth(), label.getHeight()); //移动 JLabel
				mousePos = e.getLocationOnScreen(); //更新鼠标坐标
			}
		});
	}

	public static void main(String[] arg)
		{ new DemoFrame("示例-4.3", 480, 360).setVisible(true); }
}
///:~

5. 适配器

MouseListener、MouseMotionListener 监听器的适配器都是 MouseAdapter,它同时也是 MouseWheelListener(鼠标滚轮监听器)的适配器(它同时导出自这 3 3 3 个监听器接口)。

  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Java 2实用教程(第三版)实验指导与习题解答 清华大学出版社 (编著 耿祥义 张跃平) 实验模版代码 建议使用文档结构图 (选择Word菜单→视图→文档结构图) 上机实践1 初识Java 4 实验1 一个简单的应用程序 4 实验2 一个简单的Java Applet程序 4 实验3 联合编译 5 上机实践2 基本数据类型与控制语句 6 实验1 输出希腊字母表 6 实验2 回文数 6 实验3 猜数字游戏 8 上机实践3 类与对象 9 实验1 三角形、梯形和圆形的类封装 9 实验2 实例成员与类成员 12 实验3 使用package语句与import语句 13 上机实践4 继承与接口 15 实验1 继承 15 实验2 上转型对象 17 实验3 接口回调 18 上机实践5 字符串、时间与数字 19 实验1 String类的常用方法 19 实验2 比较日期的大小 21 实验3 处理大整数 22 上机实践6 组件及事件处理 23 实验1 算术测试 23 实验2 信号灯 25 实验3 布局与日历 28 上机实践7 组件及事件处理2 31 实验1 方程求根 31 实验2 字体对话框 34 实验3 英语单词拼写训练 37 上机实践8 多线程 41 实验1 汉字打字练习 41 实验2 旋转的行星 43 实验3 双线程接力 47 上机实践9 输入输出流 50 实验1 学读汉字 50 实验2 统计英文单词字 53 实验2 读取Zip文件 56 上机实践10 Java 中的网络编程 57 实验1 读取服务器端文件 57 实验2 使用套接字读取服务器端对象 59 实验3 基于UDP的图像传输 62 上机实践11 数据结构 66 实验1 扫雷小游戏 66 实验2 排序与查找 70 实验3 使用TreeSet排序 72 上机实践12 java Swing 74 实验1 JLayeredPane分层窗格 74 实验2 使用表格显示日历 75 实验3 多文档界面(MDI) 78 上机实践1 初识Java 实验1 一个简单的应用程序 2.模板代码 Hello.java package 实验一; public class Hello { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("你好,很高兴学习Java"); //命令行窗口输出"你好,很高兴学习Java" A a=new A(); a.fA(); } } class A { void fA() {System.out.println("we are student"); } } 实验2 一个简单的Java Applet程序 2.模板代码 FirstApplet.java import java.applet.*; import java.awt.*; public class FirstApplet extends Applet { public void paint(Graphics g) { g.setColor(Color.blue); g.drawString("这是一个Java Applet 程序",10,30);//在Java Applet中绘制一行文字:“这是一个Java Applet 程序” g.setColor(Color.red); g.setFont(new Font("宋体",Font.BOLD,36)); g.drawString("我改变了字体",20,50);//在Java Applet中绘制一行文字:“我改变了字体” } }实验3 联合编译 2.模板代码 public class MainClass { public static void main (String args[ ]) { System.out.println("你好,只需编译我") ; //命令行窗口输出"你好,只需编译我" A a=new A(); a.fA(); B b=new B(); b.fB(); } } public class A { void fA() {
6.2.4 事件适配器 适配器类实现一个对应的所有接口,只是方法为空。 public abstract class WindowAdapter implements WindowListener { public void windowOpened(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowClosed(WindowEvent e) {} public void windowClosing(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} } 表6.1 Listener接口与对应的适配器(Adapter)类 接口名称 适配器名称 ComponentListener ComponentAdapter ContainerListener ContainerAdapter FocusListener FocusAdapter KeyListener KeyAdapter MouseListener MouseAdapter MouseMotionListener MouseMotionAdapter WindowListener WindowAdapter (7)鼠标运动事件 鼠标运动事件发生在鼠标移过某个组件时。 任何组件都可以产生这些事件,通过接口 MouseMotionListener 实现。 该接口有两个方法: mouseDragged(MouseEvent) mouseMove(MouseEvent) MouseMotionListener 没有自己的事件类型,替代它的是 MouseEvent 。 被用在 MouseEvent 对象上的方法它都可以使用: getClickCount( ) 返回鼠标被单击次数(整数) getPoint( ) 返回鼠标被单击位置的 x ,y 坐标 getX( ) 返回 x 位置 getY( ) 返回 y 位置 (8)窗口事件(WindowEvent) 窗口事件发生在用户打开或关闭一个诸如 Frame 或 Window 的窗口时。任何组件都可以产生这些事件,为了支持它们,类必须实现接口:WindowListener。 接口 WindowListener 中有七个方法: windowActivated(WindowEvent) 窗口被激活 windowClosed (WindowEvent) 窗口已关闭 windowClosing (WindowEvent) 窗口正在关闭 windowDeactivated (WindowEvent) 窗口失效 windowDeiconified (WindowEvent) 窗口正常化时 windowIconified (WindowEvent) 窗口最小化时 windowOpened (WindowEvent) 窗口被打开 (5)键盘事件(KeyEvent) 发生在键盘上的某个键被按下时。 类为了能够处理这些事件必须实现接口 KeyListener 。 每个产生一个键盘事件的组件上要调用方法 addKeyListener( ) 在接口 KeyListener 中有三个方法: public void keyPressed(KeyEvent evt) { //…… } public void keyReleased(KeyEvent evt) { //…… } public void keyTyped(KeyEvent evt) { //…… } 在 KeyEvent 对象上可以使用的方法: getKeyChar( ) 返回与事件相关的键盘字符的 Unicode 码 . . . . . . . . . . . . . .
题目:简易计算器的设计 一、设计概要 1、设计内容 计算器的设计使用图形用户界面实现,能够进行简单的加、减、乘、除四则计算 ; 参与运算的数字通过点击按钮输入。 2、程序流程图 详细设计 import java.awt.BorderLayout; //导入AWT页面设置类 import java.awt.Button; //导入AWT按钮类 import java.awt.Frame; import java.awt.GridLayout; import java.awt.Panel; import java.awt.TextField; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; //导入AWT鼠标监视器 import java.awt.event.WindowEvent; import java.awt.event.WindowListener;//导入AWT窗口监视器 //创建计算器的主窗口,该类含有main函数 public class Calculator { public static void main(String[] args) { //创建Frame对象 Frame f = new Frame("Calculator"); //创建文本框,用于接收数字和操作 final TextField tf = new TextField(); //声明一个面板用于存放按钮 Panel p = new Panel(); f.setLayout(new BorderLayout()); //将文本框放在北部 f.add(tf, BorderLayout.NORTH); //将按钮放于中部 f.add(p, BorderLayout.CENTER); //设置布局模式 p.setLayout(new GridLayout(4, 4)); //创建16个按钮 Button one = new Button("1"); Button two = new Button("2"); Button three = new Button("3"); Button four = new Button("4"); Button five = new Button("5"); Button six = new Button("6"); Button seven = new Button("7"); Button eight = new Button("8"); Button nine = new Button("9"); Button zero = new Button("0"); Button add = new Button("+"); Button sub = new Button("-"); Button mul = new Button("*"); Button div = new Button("/"); Button decimal = new Button("."); final Button equal = new Button("="); //将按钮添加到P p.add(one); p.add(two); p.add(three); p.add(four); p.add(five); p.add(six); p.add(seven); p.add(eight); p.add(nine); p.add(zero); p.add(add); p.add(sub); p.add(mul); p.add(div); p.add(decimal); p.add(equal); final String[] ary = {"", null, ""}; //该类为主类创建数字按钮对象 class NumMouseListener implements MouseListener{ public void mouseClicked(MouseEvent e) { String num = ((Button)e.getSource()).getLabel().trim(); if(ary[1] == null) { ary[0] = ary[0] + "" + num; } else{ ary[2] = ary[2] + "" + num; } tf.setText(tf.getText() + "" + num); } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(Mous
java网络五子棋 下面的源代码分为4个文件; chessClient.java:客户端主程序。 chessInterface.java:客户端的界面。 chessPad.java:棋盘的绘制。 chessServer.java:服务器端。 可同时容纳50个人同时在线下棋,聊天。 没有加上详细注释,不过绝对可以运行,j2sdk1.4下通过。 /********************************************************************************************* 1.chessClient.java **********************************************************************************************/ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; class clientThread extends Thread { chessClient chessclient; clientThread(chessClient chessclient) { this.chessclient=chessclient; } public void acceptMessage(String recMessage) { if(recMessage.startsWith("/userlist ")) { StringTokenizer userToken=new StringTokenizer(recMessage," "); int userNumber=0; chessclient.userpad.userList.removeAll(); chessclient.inputpad.userChoice.removeAll(); chessclient.inputpad.userChoice.addItem("所有人"); while(userToken.hasMoreTokens()) { String user=(String)userToken.nextToken(" "); if(userNumber>0 && !user.startsWith("[inchess]")) { chessclient.userpad.userList.add(user); chessclient.inputpad.userChoice.addItem(user); } userNumber++; } chessclient.inputpad.userChoice.select("所有人"); } else if(recMessage.startsWith("/yourname ")) { chessclient.chessClientName=recMessage.substring(10); chessclient.setTitle("Java五子棋客户端 "+"用户名:"+chessclient.chessClientName); } else if(recMessage.equals("/reject")) { try { chessclient.chesspad.statusText.setText("不能加入游戏"); chessclient.controlpad.cancelGameButton.setEnabled(false); chessclient.controlpad.joinGameButton.setEnabled(true); chessclient.controlpad.creatGameButton.setEnabled(true); } catch(Exception ef) { chessclient.chatpad.chatLineArea.setText("chessclient.chesspad.chessSocket.close无法关闭"); } chessclient.controlpad.joinGameButton.setEnabled(true); } else if(recMessage.startsWith("/peer ")) { chessclient.chesspad.chessPeerName=recMessage.substring(6); if(chessclient.isServer) { chessclient.chesspad.chessColor=1; chessclient.chesspad.isMouseEnabled=true; chessclient.chesspad.statusText.setText("请黑棋下子"); } else if(chessclient.isClient) { chessclient.chesspad.chessColor=-1; chessclient.chesspad.statusText.setText("已加入游戏,等待对方下子..."); } } else if(recMessage.equals("/youwin")) { chessclient.isOnChess=false; chessclient.chesspad.chessVictory(chessclient.chesspad.chessColor); chessclient.chesspad.statusText.setText("对方退出,请点放弃游戏退出连接"); chessclient.chesspad.isMouseEnabled=false; } else if(recMessage.equals("/OK")) { ……………………………………………………………………………………catch(Exception ee) { } } System.exit(0); } public void windowActivated(WindowEvent ea) { } }); add(westPanel,BorderLayout.WEST); add(centerPanel,BorderLayout.CENTER); add(southPanel,BorderLayout.SOUTH); pack(); setSize(670,548); setVisible(true); setResizable(false); validate(); } public boolean connectServer(String serverIP,int serverPort) throws Exception { try { chatSocket=new Socket(serverIP,serverPort); in=new DataInputStream(chatSocket.getInputStream()); out=new DataOutputStream(chatSocket.getOutputStream()); clientThread clientthread=new clientThread(this); clientthread.start(); isOnChat=true; return true; } catch(IOException ex) { chatpad.chatLineArea.setText("chessClient:connectServer:无法连接,建议重新启动程序 \n"); } return false; } public void actionPerformed(ActionEvent e) { if(e.getSource()==controlpad.connectButton) { host=chesspad.host=controlpad.inputIP.getText(); try { if(connectServer(host,port)) { chatpad.chatLineArea.setText(""); controlpad.connectButton.setEnabled(false); controlpad.creatGameButton.setEnabled(true); controlpad.joinGameButton.setEnabled(true); chesspad.statusText.setText("连接成功,请创建游戏或加入游戏"); } } catch(Exception ei) { chatpad.chatLineArea.setText("controlpad.connectButton:无法连接,建议重新启动程序 \n"); } } if(e.getSource()==controlpad.exitGameButton) { if(isOnChat) { try { chatSocket.close(); } catch(Exception ed) { } } if(isOnChess || isGameConnected) { try { chesspad.chessSocket.close(); } catch(Exception ee) { } } System.exit(0); } if(e.getSource()==controlpad.joinGameButton) { String selectedUser=userpad.userList.getSelectedItem(); if(selectedUser==null || selectedUser.startsWith("[inchess]") || selectedUser.equals(chessClientName)) { chesspad.statusText.setText("必须先选定一个有效用户"); } else { try { if(!isGameConnected) { if(chesspad.connectServer(chesspad.host,chesspad.port)) { isGameConnected=true; isOnChess=true; isClient=true; controlpad.creatGameButton.setEnabled(false); controlpad.joinGameButton.setEnabled(false); controlpad.cancelGameButton.setEnabled(true); chesspad.chessthread.sendMessage("/joingame "+userpad.userList.getSelectedItem()+" "+chessClientName); } } else { isOnChess=true; isClient=true; controlpad.creatGameButton.setEnabled(false); controlpad.joinGameButton.setEnabled(false); controlpad.cancelGameButton.setEnabled(true); chesspad.chessthread.sendMessage("/joingame "+userpad.userList.getSelectedItem()+" "+chessClientName); } } catch(Exception ee) { isGameConnected=false; isOnChess=false; isClient=false; controlpad.creatGameButton.setEnabled(true); controlpad.joinGameButton.setEnabled(true); controlpad.cancelGameButton.setEnabled(false); chatpad.chatLineArea.setText("chesspad.connectServer无法连接 \n"+ee); } } } if(e.getSource()==controlpad.creatGameButton) { try { if(!isGameConnected) { if(chesspad.connectServer(chesspad.host,chesspad.port)) { isGameConnected=true; isOnChess=true; isServer=true; controlpad.creatGameButton.setEnabled(false); controlpad.joinGameButton.setEnabled(false); controlpad.cancelGameButton.setEnabled(true); chesspad.chessthread.sendMessage("/creatgame "+"[inchess]"+chessClientName); } } else { isOnChess=true; isServer=true; controlpad.creatGameButton.setEnabled(false); controlpad.joinGameButton.setEnabled(false); controlpad.cancelGameButton.setEnabled(true); chesspad.chessthread.sendMessage("/creatgame "+"[inchess]"+chessClientName); } } catch(Exception ec) { isGameConnected=false; isOnChess=false; isServer=false; controlpad.creatGameButton.setEnabled(true); controlpad.joinGameButton.setEnabled(true); controlpad.cancelGameButton.setEnabled(false); ec.printStackTrace(); chatpad.chatLineArea.setText("chesspad.connectServer无法连接 \n"+ec); } } if(e.getSource()==controlpad.cancelGameButton) { if(isOnChess) { chesspad.chessthread.sendMessage("/giveup "+chessClientName); chesspad.chessVictory(-1*chesspad.chessColor); controlpad.creatGameButton.setEnabled(true); controlpad.joinGameButton.setEnabled(true); controlpad.cancelGameButton.setEnabled(false); chesspad.statusText.setText("请建立游戏或者加入游戏"); } if(!isOnChess) { controlpad.creatGameButton.setEnabled(true); controlpad.joinGameButton.setEnabled(true); controlpad.cancelGameButton.setEnabled(false); chesspad.statusText.setText("请建立游戏或者加入游戏"); } isClient=isServer=false; } } public void keyPressed(KeyEvent e) { TextField inputWords=(TextField)e.getSource(); if(e.getKeyCode()==KeyEvent.VK_ENTER) { if(inputpad.userChoice.getSelectedItem().equals("所有人")) { try { out.writeUTF(inputWords.getText()); inputWords.setText(""); } catch(Exception ea) { chatpad.chatLineArea.setText("chessClient:KeyPressed无法连接,建议重新连接 \n"); userpad.userList.removeAll(); inputpad.userChoice.removeAll(); inputWords.setText(""); controlpad.connectButton.setEnabled(true); } } else { try { out.writeUTF("/"+inputpad.userChoice.getSelectedItem()+" "+inputWords.getText()); inputWords.setText(""); } catch(Exception ea) { chatpad.chatLineArea.setText("chessClient:KeyPressed无法连接,建议重新连接 \n"); userpad.userList.removeAll(); inputpad.userChoice.removeAll(); inputWords.setText(""); controlpad.connectButton.setEnabled(true); } } } } public void keyTyped(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public static void main(String args[]) { chessClient chessClient=new chessClient(); } } /****************************************************************************************** 下面是:chessInteface.java ******************************************************************************************/ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; class userPad extends Panel { List userList=new List(10); userPad() { setLayout(new BorderLayout()); for(int i=0;i<50;i++) { userList.add(i+"."+"没有用户"); } add(userList,BorderLayout.CENTER); } } class chatPad extends Panel { TextArea chatLineArea=new TextArea("",18,30,TextArea.SCROLLBARS_VERTICAL_ONLY); chatPad() { setLayout(new BorderLayout()); add(chatLineArea,BorderLayout.CENTER); } } class controlPad extends Panel { Label IPlabel=new Label("IP",Label.LEFT); TextField inputIP=new TextField("localhost",10); Button connectButton=new Button("连接主机"); Button creatGameButton=new Button("建立游戏"); Button joinGameButton=new Button("加入游戏"); Button cancelGameButton=new Button("放弃游戏"); Button exitGameButton=new Button("关闭程序"); controlPad() { setLayout(new FlowLayout(FlowLayout.LEFT)); setBackground(Color.pink); add(IPlabel); add(inputIP); add(connectButton); add(creatGameButton); add(joinGameButton); add(cancelGameButton); add(exitGameButton); } } class inputPad extends Panel { TextField inputWords=new TextField("",40); Choice userChoice=new Choice(); inputPad() { setLayout(new FlowLayout(FlowLayout.LEFT)); for(int i=0;i<50;i++) { userChoice.addItem(i+"."+"没有用户"); } userChoice.setSize(60,24); add(userChoice); add(inputWords); } } /********************************************************************************************** 下面是:chessPad.java **********************************************************************************************/ import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.*; class chessThread extends Thread { chessPad chesspad; chessThread(chessPad chesspad) { this.chesspad=chesspad; } public void sendMessage(String sndMessage) { try { chesspad.outData.writeUTF(sndMessage); } catch(Exception ea) { System.out.println("chessThread.sendMessage:"+ea); } } public void acceptMessage(String recMessage) { if(recMessage.startsWith("/chess ")) { StringTokenizer userToken=new StringTokenizer(recMessage," "); String chessToken; String[] chessOpt={"-1","-1","0"}; int chessOptNum=0; while(userToken.hasMoreTokens()) { chessToken=(String)userToken.nextToken(" "); if(chessOptNum>=1 && chessOptNum<=3) { chessOpt[chessOptNum-1]=chessToken; } chessOptNum++; } chesspad.netChessPaint(Integer.parseInt(chessOpt[0]),Integer.parseInt(chessOpt[1]),Integer.parseInt(chessOpt[2])); } else if(recMessage.startsWith("/yourname ")) { chesspad.chessSelfName=recMessage.substring(10); } else if(recMessage.equals("/error")) { chesspad.statusText.setText("错误:没有这个用户,请退出程序,重新加入"); } else { //System.out.println(recMessage); } } public void run() { String message=""; try { while(true) { message=chesspad.inData.readUTF(); acceptMessage(message); } } catch(IOException es) { } } } class chessPad extends Panel implements MouseListener,ActionListener { int chessPoint_x=-1,chessPoint_y=-1,chessColor=1; int chessBlack_x[]=new int[200]; int chessBlack_y[]=new int[200]; int chessWhite_x[]=new int[200]; int chessWhite_y[]=new int[200]; int chessBlackCount=0,chessWhiteCount=0; int chessBlackWin=0,chessWhiteWin=0; boolean isMouseEnabled=false,isWin=false,isInGame=false; TextField statusText=new TextField("请先连接服务器"); Socket chessSocket; DataInputStream inData; DataOutputStream outData; String chessSelfName=null; String chessPeerName=null; String host=null; int port=4331; chessThread chessthread=new chessThread(this); chessPad() { setSize(440,440); setLayout(null); setBackground(Color.pink); addMouseListener(this); add(statusText); statusText.setBounds(40,5,360,24); statusText.setEditable(false); } public boolean connectServer(String ServerIP,int ServerPort) throws Exception { try { chessSocket=new Socket(ServerIP,ServerPort); inData=new DataInputStream(chessSocket.getInputStream()); outData=new DataOutputStream(chessSocket.getOutputStream()); chessthread.start(); return true; } catch(IOException ex) { statusText.setText("chessPad:connectServer:无法连接 \n"); } return false; } public void chessVictory(int chessColorWin) { this.removeAll(); for(int i=0;i<=chessBlackCount;i++) { chessBlack_x[i]=0; chessBlack_y[i]=0; } for(int i=0;i<=chessWhiteCount;i++) { chessWhite_x[i]=0; chessWhite_y[i]=0; } chessBlackCount=0; chessWhiteCount=0; add(statusText); statusText.setBounds(40,5,360,24); if(chessColorWin==1) { chessBlackWin++; statusText.setText("黑棋胜,黑:白为"+chessBlackWin+":"+chessWhiteWin+",重新开局,等待白棋下子..."); } else if(chessColorWin==-1) { chessWhiteWin++; statusText.setText("白棋胜,黑:白为"+chessBlackWin+":"+chessWhiteWin+",重新开局,等待黑棋下子..."); } } public void getLocation(int a,int b,int color) { if(color==1) { chessBlack_x[chessBlackCount]=a*20; chessBlack_y[chessBlackCount]=b*20; chessBlackCount++; } else if(color==-1) { chessWhite_x[chessWhiteCount]=a*20; chessWhite_y[chessWhiteCount]=b*20; chessWhiteCount++; } } public boolean checkWin(int a,int b,int checkColor) { int step=1,chessLink=1,chessLinkTest=1,chessCompare=0; if(checkColor==1) { chessLink=1; for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a+step)*20==chessBlack_x[chessCompare]) && ((b*20)==chessBlack_y[chessCompare])) { chessLink=chessLink+1; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a-step)*20==chessBlack_x[chessCompare]) && (b*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } chessLink=1; chessLinkTest=1; for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if((a*20==chessBlack_x[chessCompare]) && ((b+step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if((a*20==chessBlack_x[chessCompare]) && ((b-step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } chessLink=1; chessLinkTest=1; for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a-step)*20==chessBlack_x[chessCompare]) && ((b+step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a+step)*20==chessBlack_x[chessCompare]) && ((b-step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } chessLink=1; chessLinkTest=1; for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a+step)*20==chessBlack_x[chessCompare]) && ((b+step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } } } if(chessLink==(chessLinkTest+1)) chessLinkTest++; else break; } for(step=1;step<=4;step++) { for(chessCompare=0;chessCompare<=chessBlackCount;chessCompare++) { if(((a-step)*20==chessBlack_x[chessCompare]) && ((b-step)*20==chessBlack_y[chessCompare])) { chessLink++; if(chessLink==5) { return(true); } }
中文名: Java2游戏编程 原名: Java 2 Game Programming 作者: Thomas Petchel译者: 晏利斌 孙淑敏 邵荣 资源格式: PDF 版本: 扫描版 出版社: 清华大学出版社书号: 7302112932发行时间: 2005年08月 地区: 大陆 语言: 简体中文 简介: 内容介绍:   你经常看到有人在玩手机游戏吧,那些手机游戏基本上是用Java编写的。Java已经成熟了,它现在是一种开发能够多种平台上运行的中小型游戏的很好方式。本书将向读者展示用Java语言和它的类库创建2D游戏,所涉及的主题包括高速性能、双缓冲图像、动画、声音、媒体控制、I/O和网络支持等。将带领大家一步一步学习编写Java游戏,最终打造属于自己的Java游戏。 目录: 第1篇 步入Java丛林:从Java2 API开始 第1章 Java2软件开发工具包 1.1 Java简史 1.2 为什么在游戏中使用Java 1.3 为Java准备系统 1.3.1 安装Java SDK 1.3.2 编译和运行Java程序 1.3.3 使用命令行 1.3.4 使用集成开发环境(IDE) 1.3.5 关于Java2文档的说明 1.4 总结 第2章 预备:学习Java2 API 2.1 Game Over! 程序 2.1.1 import语句 2.1.2 给Java代码加注释 2.1.3 Java类声明 2.1.4 Java方法声明 2.1.5 Java中的代码块 2.1.6 Java程序组成部分的关键点回顾 2.2 比特和字节:原始的Java类型 2.2.1 基本的整数类型 2.2.2 浮点类型 2.2.3 Char类型 2.2.4 布尔型 2.2.5 String类型 2.2.6 强制转换变量类型 2.2.7 Java数据类型、数组和标识符需要记忆的要点 2.3 Java中的运算符 2.3.1 赋值运算符 2.3.2 比较运算符 2.3.3 算术运算符 2.3.4 自增和自减运算符 2.3.5 更多的整数运算符 2.3.6 使用点运算符 2.3.7 instanceof运算符 2.3.8 优先级顺序 2.3.9 关于运算符的记忆要点 2.4 条件语句 2.4.1 switch语句 2.4.2 Java中的循环语句 2.4.3 用break、continue和return提前退出循环 2.5 处理运行时异常 2.5.1 使用try和catch块 2.5.2 使用throws子句 2.5.3 关于流程控制语句的记忆要点 2.6 总结 2.7 练习 第3章 带有类的语言:Java面向对象程序设计 3.1 设计一个Java类 3.2 方法的魔法 3.3 关于方法的更多话题 3.3.1 构造函数方法 3.3.2 访问方法 3.3.3 类方法 3.3.4 “其他”方法 3.4 继承 3.5 抽象类 3.6 类修饰符 3.7 接口 3.8 快捷地创建类 3.9 包 3.10 总结 3.11 练习 第4章 Java API为你服务:常用Java类 4.1 java.lang包 4.1.1 java.lang.Object 4.1.2 java.lang.String 4.1.3 java.lang.StringBuffer 4.1.4 封装类 4.1.5 java.lang.Math 4.1.6 java.lang.System 4.1.7 java.lang.Cloneable 4.1.8 java.lang.Thread 4.2 java.io包 4.3 java.util包 4.3.1 java.util.StringTokenizer 4.3.2 java.util.Random 4.3.3 Java2集合框架 4.4 总结 4.5 练习 第2篇 Java 2-D图像开发和抽象Window工具包 第5章 Applet基础 5.1 什么是Java applet 5.2 Applet和Application的比较 5.3 Applet的组成和生命周期 5.4 一个Applet例子 5.5 运行Java Applets 5.6 通用AWT组件 5.6.1 按钮 5.6.2 单选按钮(Radio Button) 5.6.3 作出重要选择 5.6.4 循环播放声音文件 5.6.5 文本域 5.6.6 标签 5.7 布局管理 5.7.1 FlowLayout类 5.7.2 GridLayout类 5.7.3 BorderLayout类 5.7.4 CardLayout类 5.8 容器(Container) 5.9 创建自定义组件 5.10 一个完整的例子 5.11 总结 5.12 练习 第6章 监听用户 6.1 EventLi

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值