提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 引言
- 一、问题来源以及问题描述
- 1.问题来源
- 2.问题描述
- 二、问题分析
- 三、如何解决
- 1.尝试过程
- 2.解决方案
- 3.该题完整代码
- 四、总结
- 五、个人感想
引言
这篇文章包含了我探索这个问题的过程以及思路,大家可以顺着我的思路看下去,也可以直接看结论,看我的解决方案,希望对大家有帮助。
一、问题来源以及问题描述
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;//阻止单击事件发生
}
}
}
});
}
四、总结
一般情况下双击事件执行前总是会执行双击事件,我们仅仅通过推迟单击事件执行不能解决问题,但我们可以先推迟单击事件执行,然后在执行双击事件时做出一些操作来阻止后续单击事件的执行,从而也就解决了问题。
五、个人感想
这是我第一次在上写文章,没什么经验,这也导致了我的文章会很啰嗦,也可能伴随着很多不足,或者纰漏。但是算是一个开始,我之后会多多发表文章,来记录我的学习过程中遇到的问题,以及分析我的经验!!!