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); //鼠标离开

事实上,前三个方法的触发,不考虑 按下/松开的是哪个键、是否属于一个双击等。
即只要发生了一次如注释所描述的事件,相应方法就会被触发一次。

“鼠标浮动”,指的是鼠标移动到控件上、但没有点击的时候。
严肃点应该叫“进入”(大多数博客也是这么写的),但我个人感觉“浮动”更形象。

1.1 注意事项 1:瞬时行为

rt,“鼠标浮动”、“鼠标离开”等描述,指的并非一种长时间的状态,而是 一瞬间的状态的改变
(有点像英语中 wearput on 的区别,而上述方法 均属后者

废话不多说,上丑图:
代码在 1.3 节找

1.2 注意事项 2:事件的触发

这次的关注点在鼠标监听器的前三个方法。

还记得吗?“鼠标按下”、“鼠标松开”这样的方法言简意赅,没啥歧义。于是问题就出在:“鼠标点击”到底是指什么?
其实仍然可以用生活中的经验来感性理解。平时我们要是说“点一下这个”,意思不就是“先按下去、再松开来”吗?
事实上,“鼠标点击”有点像是对前两者的“总结”。当一次“鼠标按下”加“鼠标松开”依次被触发后,紧接着就会调用“鼠标点击”事件。

鼠标点击 { 鼠标按下 鼠标松开 鼠标点击\begin{cases}鼠标按下\\鼠标松开\end{cases} 鼠标点击{鼠标按下鼠标松开

至于它们的触发顺序:

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

图中,左侧的事件有点像是右侧事件的“先决条件”,即“有左才有右”,一步一步向右触发。

下面是一些小例子 1

  • 鼠标在别处按下,“拖到”控件中再松开。
    似乎应当触发一个“鼠标松开”事件。不过根据上述,由于并没有在控件中触发“鼠标按下”,自然也不会有“鼠标松开”。最后结果是并未触发这 3 3 3 个事件中任意一个(如下动图所示):
    (控制台输出为“鼠标浮动”)

  • 鼠标在控件中按下,“拖到”别处再松开。
    由于没有在控件中进行“鼠标松开”,自然也不会有“鼠标点击”。然而很奇怪,最终触发“鼠标按下”与“鼠标松开”(如下动图所示):
    (出乎我的意料)

1.3 示例代码

1.1 和 1.2 节中的动图示例就是使用的如下代码:

import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class DemoFrame {

	public static void main(String[] args) {
		JFrame frame = new JFrame("示例-1.3");

		JButton button = new JButton("I am a button"); //控件,后面将为它添加鼠标监听器

		JTextArea console = new JTextArea(9, 16); //用于显示输出的“控制台”
		JScrollPane panel = new JScrollPane(console); //防止输出过长,为“控制台”添加滚动条

		console.setEditable(false); //禁止修改文本
		console.setFocusable(false); //禁止框选文本

		button.addMouseListener(new MouseListener() { //用于观察各个方法的触发
			@Override public void mouseClicked(MouseEvent e) { console.append("Mouse Clicked!\n"); }
			@Override public void mousePressed(MouseEvent e) { console.append("Mouse Pressed!\n"); }
			@Override public void mouseReleased(MouseEvent e) { console.append("Mouse Released!\n"); }
			@Override public void mouseEntered(MouseEvent e) { console.append("Mouse Entered!\n"); }
			@Override public void mouseExited(MouseEvent e) { console.append("Mouse Exited!\n"); }
		});

		//测试代码:
		frame.setSize(480, 270);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.add(button, BorderLayout.CENTER);
		frame.add(panel, BorderLayout.SOUTH);
		frame.setVisible(true);
	}
}

效果就不用再录张图了吧?上面已经有那么多了。

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

此监听器同样适用于 JComponent 及其派生类。

虽然 MouseMotionListener 也是个监听器,但 Swing 并没有提供“MouseMotionEvent”这样的事件,所以 MouseListener 和 MouseMotionListener 都是用的 MouseEvent 类。(详见后文)

方法介绍:

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

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

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

3.0 链接:官方文档

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

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

要是所有人都懂得自己翻文档,我就没必要写这篇博客了。(bushi)

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

返回出事时鼠标的绝对坐标。(大雾)

“绝对坐标”指相对于整个电脑屏幕的坐标。以左上角为原点。

public int getXOnScreen(); //X 坐标,非负整数(毕竟鼠标又不能跑出屏幕)
public int getYOnScreen(); //Y 坐标,同上
public Point getLocationOnScreen(); //X 和 Y 坐标包成一块返回

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

public int x, y;

闲话:注意到它们既没有被 final 关键字修饰、也缺少 synchronized 的 Getter、Setter 方法,因此 Point 类是可变的。(也许因为 Swing 中广泛地使用线程封闭技术)

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

log.info(e.getLocationOnScreen());
//大多数 Logger 会自动调用 Point 类的 toString 方法
//例:java.awt.Point[x=0,y=0]

out.printf("(%d, %d)\n", e.getXOnScreen(), e.getYOnScreen());
//用 printf 格式化,推荐方式
//大多数 Logger 肯定也会提供类似 printf 的输出方式,如 log4j

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

事件发生时鼠标相对于此控件的坐标。

相对坐标就不多说了吧,你把绝对坐标看成相对坐标的特例(以整个屏幕为参照系),类比一下即可。

public int getX(); //X 坐标,注意可能出现负数
public int getY(); //Y 坐标,同上
public java.awt.Point getPoint(); //返回鼠标指针的相对坐标

3.3 getClickCount()

仅在 MouseListener 的前三个事件(“鼠标按下”、“鼠标松开”、“鼠标点击”)中,返回值有意义。

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

按下不同键不构成双击。例如 1,按顺序快速点击左键与右键,则两次都返回 1 1 1

如果是在没有鼠标点击的事件中调用此方法(“鼠标浮动”等),则返回 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;	//没有按下鼠标按键(例如“鼠标浮动”等事件)
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 示例:输出事件发生时间(不同格式)

平时可以用 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 formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info(formatter.format(e.getWhen())); //如:“2023-02-03 18:55:07”

甚至还可以这样:out.printf("%tc", e.getWhen());
示例输出:周五 2月 03 18:55:07 CST 2023

3.6 paramString()

返回标识此事件的参数字符串,此方法对于事件日志记录和调试很有用(至少文档里是这么说的)。

示例输出:

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

看到这里,你可能会说:?

……

好吧,正常一点:

示例输出通用输出简要解释参见章节
MOUSE_PRESSED%s触发的事件类型 3.9 3.9 3.9
(52,93)(%d,%d)触发事件时,鼠标相对于此组件的坐标 3.2 3.2 3.2
absolute(59,163)absolute(%d,%d)触发事件时,鼠标相对于屏幕的坐标 3.1 3.1 3.1
button=1button=%d触发事件的鼠标按键 3.4 3.4 3.4
modifiers=Ctrl+Button1modifiers=%s触发事件的修饰符 3.7 3.7 3.7
extModifiers=CtrlextModifiers=%s触发事件的修饰符 3.8 3.8 3.8
clickCount=2clickCount=%dcombo 的次数 3.3 3.3 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 种情况(测试于台式机,Win10):

一、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 就是疯狂复制粘贴,这里就贴一个简短的反射代码吧(尽管几乎没有实用意义 Q A Q QAQ QAQ):

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 is .");
}

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

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

你可能注意到,这里顺带提了两个于 MouseEvent 中定义的很奇怪的常量,也就是 MOUSE_FIRST 和 MOUSE_LAST。
顾名思义,它们跟鼠标什么的没啥关系,而是描述了所有事件常量的值的上下界,即上述所有事件常量的值刚好不重不漏取完 [ M O U S E _ F I R S T , M O U S E _ L A S T ] [\mathsf{MOUSE\_FIRST}, \mathsf{MOUSE\_LAST}] [MOUSE_FIRST,MOUSE_LAST]
至于作用,可以参考代码的第 6 6 6 行,即用于检测给定 id 的合法性。

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() {
		@Override
		public void mouseMoved(MouseEvent e) {
			label.setText(String.format("X=%d, Y=%d", e.getX(), e.getY()));
		}

		@Override
		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.1

4.2 鼠标拖动 JLabel

利用 MouseMotionListener,在鼠标拖动时让 JLabel 的坐标保持和鼠标同步移动,实现拖动效果。1

示例 4.2

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;

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

	private Point mousePos; //跟踪鼠标坐标
	private JLabel label = new JLabel("I am a label.", 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 / 4, height / 8);
		label.setBorder(BorderFactory.createLineBorder(Color.BLACK, 2)); //黑色边框,便于拖动观察

		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.2", 480, 360).setVisible(true); }
}

5. 适配器

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

适配器:例如,你想监听某个控件的“鼠标点击”事件,尽管你只需要 mouseClicked() 这一个方法,但由于 MouseListener 是一个接口,你还必须要实现它的其他方法:

component.addMouseListener(new MouseListener() {
	@Override
	public void mouseClicked(MouseEvent e) {
		System.out.println("hello, world");
	}

	@Override public void mousePressed(MouseEvent e) {}
	@Override public void mouseReleased(MouseEvent e) {}
	@Override public void mouseEntered(MouseEvent e) {}
	@Override public void mouseExited(MouseEvent e) {}
});

这样相当麻烦且相当不美观,于是有了:

component.addMouseListener(new MouseAdapter() {
	@Override
	public void mouseClicked(MouseEvent e) {
		System.out.println("hello, world");
	}
});

为什么可以这样做呢?瞅一眼 MouseAdapter 的定义吧:

public abstract class MouseAdapter implements MouseListener, MouseWheelListener, MouseMotionListener {
	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) {}
	public void mouseWheelMoved(MouseWheelEvent e) {}
	public void mouseDragged(MouseEvent e) {}
	public void mouseMoved(MouseEvent e) {}
}

(略有删改,请以您的 JDK 的实际实现为准)

最后,友情提示:使用适配器时请注意加上 @Override 注解,否则一发 mouseCilcked 可以让你调半年。


  1. 这里动图经过特殊处理:当鼠标左键处于按下状态时,鼠标周围出现黄色高亮;同理中键为蓝、右键为红。 ↩︎ ↩︎ ↩︎

  • 11
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Java鼠标点击事件监听可以通过实现 MouseListener 接口来完成。 MouseListener 接口定义了以下五个方法: - void mouseClicked(MouseEvent e):鼠标单击事件 - void mousePressed(MouseEvent e):鼠标按下事件 - void mouseReleased(MouseEvent e):鼠标释放事件 - void mouseEntered(MouseEvent e):鼠标进入组件事件 - void mouseExited(MouseEvent e):鼠标离开组件事件 要实现鼠标点击事件监听,需要创建一个类并实现 MouseListener 接口。例如: ```java import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; public class ClickListener extends JFrame implements MouseListener { public ClickListener() { super("MouseListener Demo"); setSize(300, 300); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); addMouseListener(this); setVisible(true); } public static void main(String[] args) { new ClickListener(); } @Override public void mouseClicked(MouseEvent e) { System.out.println("鼠标单击事件"); } @Override public void mousePressed(MouseEvent e) { System.out.println("鼠标按下事件"); } @Override public void mouseReleased(MouseEvent e) { System.out.println("鼠标释放事件"); } @Override public void mouseEntered(MouseEvent e) { System.out.println("鼠标进入组件事件"); } @Override public void mouseExited(MouseEvent e) { System.out.println("鼠标离开组件事件"); } } ``` 在上面的代码中,我们创建了一个类 ClickListener,并实现了 MouseListener 接口。在构造函数中,我们将当前对象作为监听器添加到 JFrame 上,这样该 JFrame 就能够监听鼠标事件了。 接下来,我们在各个监听方法中打印出相应的事件信息。当用户进行鼠标单击、按下、释放、进入组件和离开组件时,就会触发相应的监听方法,从而打印出相应的事件信息。 最后,我们创建一个 ClickListener 对象,运行程序即可看到效果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值