Java Swing 如何在不执行单击事件的情况下执行双击事件

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


引言

这篇文章包含了我探索这个问题的过程以及思路,大家可以顺着我的思路看下去,也可以直接看结论,看我的解决方案,希望对大家有帮助。

一、问题来源以及问题描述

1.问题来源

	编写Java程序,创建一个窗体,并实现交互。在窗体内“单击鼠标左键”,在光标处绘制一个“绿圆”;窗体内“单击鼠标右键”,在光标处绘制一个“红色方框”;窗体内“双击鼠标左键”,清空所有已画“圆”和“方”。
	在完成这次Java编程作业的过程中发现了此问题。

2.问题描述

	在双击鼠标左键,清空所画的圆和方时,总是会先再画出一个圆然后再清除所画的图案。也就是在执行双击事件之前总是会先执行一次单击事件。因此,如何直接执行双击事件而不执行单击事件呢?

二、问题分析

	首先、GUI中的鼠标事件的单击事件以及双击事件的区分是通过使用getClickCount()来获取点击次数,从而来判断是单击还是双击亦或是多击。而getClickCount()的值是从零开始连续增加的。双击对应值为二,单击对应值为一,因此在执行双击事件之前,单击事件就因为if条件句判断geiClickCount()的值为一而先执行了。
if(e.getClickCount()==1){//单击时
	    			if(e.getButton()==e.BUTTON1){//单击左键时
	    	    					Graphics g=getGraphics();
	    		    				g.setColor(Color.green);//设置当前颜色为绿色
	    		    				g.fillOval(e.getX(),e.getY(),60,60);
	    	    				}
	    			else if(e.getButton()==e.BUTTON3){//单击右键时
	    				Graphics g=getGraphics();
	    				g.setColor(Color.red);//设置当前颜色为红色
	    				g.fillRect(e.getX(),e.getY(),60,60);
	    			}
				}
	    		else if(e.getClickCount()==2){//双击时
	    			if(e.getButton()==e.BUTTON1){//双击左键时
	    				repaint();//清屏
	    			}
	    		}
	那么如何来解决这个问题呢,下面我来介绍我的探索过程和解决方法。

三、如何解决

1.尝试过程

	首先我想到用Timer类做延迟处理,延迟单击事件的产生,从而先执行我的双击事件,清除所画的圆和方。但是结果是在清除之后,屏幕上又会多出一个圆,也就是说在执行了双击事件后单击事件又被执行了,所以我们可以看出仅仅依靠延迟单击时间的执行并不能解决问题,因为延迟只是推迟了执行,而不是阻止执行,在这种情况下单击事件必然会被执行。
	之后我在网上搜索了类似问题,虽然没有得到我想要的结果,有些网上的方案并不能让单击事件不执行,但是大家的方向都是使用Timer类,我看到一个评论说Sun官网上也是说通过使用Timer类来解决问题。
	因此方向没有错,所以要对我们的思路进行完善和补充。
	自然而然我们想到能不能在延迟单击事件执行的这一段时间里,通过一些其他操作,例如用一个flag来判断,若是要执行双击事件flag就变为flase来预防延迟结束后单击事件的执行。最后程序运行的结果也显示这种方法是正确的。以下就是正确的解决方案。

2.解决方案

Timer timer = new Timer();
	    		flag = true;//判断是否要执行单击事件
	    		if(e.getClickCount()==1){//单击时
	    			if(e.getButton()==e.BUTTON1){//单击左键时
	    				timer.schedule(new TimerTask() {//延迟处理
	    	    			public void run() {//要延迟处理的操作
	    	    				if(flag == true) {
	    	    					Graphics g=getGraphics();
	    		    				g.setColor(Color.green);//设置当前颜色为绿色
	    		    				g.fillOval(e.getX(),e.getY(),60,60);
	    	    				}
	    	    			}
	    	    		}, 200);
	    			}
	    			else if(e.getButton()==e.BUTTON3){//单击右键时
	    				Graphics g=getGraphics();
	    				g.setColor(Color.red);//设置当前颜色为红色
	    				g.fillRect(e.getX(),e.getY(),60,60);
	    			}
	    		}
	    		else if(e.getClickCount()==2){//双击时
	    			if(e.getButton()==e.BUTTON1){//双击左键时
	    				repaint();//清屏
	    				this.flag = false;//阻止单击事件发生
	    			}
	    		}

我创建了一个boolean变量flag来判断是否要执行左键单击事件。
若为true就执行,若为false就不执行。

不执行就说明我们要执行双击事件,在这种情况下,我首先用Timer类来推迟单击事件的执行,首先执行双击事件,因为我们不需要执行单击事件,我们仅需要在双击事件中将flag变为false即可,这样在延迟结束后,if语句为假从而不执行单击事件。

最后因为我们要连续监视鼠标事件,不能将flag变为false就不管了,如果这样的话,之后就没办法执行单击事件了,使用我们还要在每次判断鼠标事件时给flag变为true。

3.该题完整代码

/*7.	编写Java程序,创建一个窗体,并实现交互。
 * 在窗体内“单击鼠标左键”,在光标处绘制一个“绿圆”;
 * 窗体内“单击鼠标右键”,在光标处绘制一个“红色方框”;
 * 窗体内“双击鼠标左键”,清空所有已画“圆”和“方”。*/
package homework;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Work0307 {
	public static void main(String args[]) {
		new Mouse();
	}
}

class Mouse extends JFrame{
	Mouse(){
		//界面准备
		this.setTitle("画图");//设置标题
		this.setBounds(100,100,400,400);//设置位置大小
		this.setVisible(true);//设置是否显示窗体
		JPanel jp = new JPanel();//添加面板
		this.add(jp);//添加到JFrame上
		jp.setBackground(Color.cyan);//设置背景颜色
		
		//事件处理
		jp.addMouseListener(new MouseAdapter(){
	    	private boolean flag;//用于设置双击时不执行单击
			public void mouseClicked(MouseEvent e){//重写mouseClicked方法
	    		Timer timer = new Timer();
	    		flag = true;//判断是否要执行单击事件
	    		if(e.getClickCount()==1){//单击时
	    			if(e.getButton()==e.BUTTON1){//单击左键时
	    				timer.schedule(new TimerTask() {//延迟处理
	    	    			public void run() {//要延迟处理的操作
	    	    				if(flag == true) {
	    	    					Graphics g=getGraphics();
	    		    				g.setColor(Color.green);//设置当前颜色为绿色
	    		    				g.fillOval(e.getX(),e.getY(),60,60);
	    	    				}
	    	    			}
	    	    		}, 200);
	    			}
	    			else if(e.getButton()==e.BUTTON3){//单击右键时
	    				Graphics g=getGraphics();
	    				g.setColor(Color.red);//设置当前颜色为红色
	    				g.fillRect(e.getX(),e.getY(),60,60);
	    			}
	    		}
	    		else if(e.getClickCount()==2){//双击时
	    			if(e.getButton()==e.BUTTON1){//双击左键时
	    				repaint();//清屏
	    				this.flag = false;//阻止单击事件发生
	    			}
	    		}
	    	}
	    });
	}

四、总结

一般情况下双击事件执行前总是会执行双击事件,我们仅仅通过推迟单击事件执行不能解决问题,但我们可以先推迟单击事件执行,然后在执行双击事件时做出一些操作来阻止后续单击事件的执行,从而也就解决了问题。

五、个人感想

这是我第一次在CSDN上写文章,没什么经验,这也导致了我的文章会很啰嗦,也可能伴随着很多不足,或者纰漏。但是算是一个开始,我之后会多多发表文章,来记录我的学习过程中遇到的问题,以及分析我的经验!!!

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃气十足

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值