题目要求:编写Java程序,创建一个窗体,并实现交互。在窗体内“单击鼠标左键”,在光标处绘制一个“绿圆”;窗体内“单击鼠标右键”,在光标处绘制一个“红色方框”;窗体内“双击鼠标左键”,清空所有已画“圆”和“方”。
采用iterator迭代器
package homework0307;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class Homework0307 {
public static void main(String[] args) {
new MyJFrame("画图");
}
}
class MyJFrame extends JFrame {
//监听鼠标当前的位置,用集合来存储这个点
// 定义一个MyPoint类型的Arrlylist(调用get()时需要)
ArrayList points;
//记录鼠标点击的次数
int mc = 0;
public MyJFrame(String title){
super(title);
setVisible(true);
setBounds(200,200,400,300);
//存鼠标正击的点
points = new ArrayList<>();
//鼠标监听器,正对这个窗口
this.addMouseListener(new MyMouseListener());
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
class MyMouseListener extends MouseAdapter {
@Override
public void mouseClicked(MouseEvent e){
mc = e.getClickCount(); //接受鼠标点击的次数
MyJFrame myJFrame = (MyJFrame) e.getSource(); //e.getSource(),返回当前对象
if(mc == 1) {
points.add(new MyPoint(e.getX(),e.getY(),e.getButton())); //单击的情况记录下单击的位置坐标并添加到集合中
}
myJFrame.repaint(); // //每次点击鼠标都需要重新画一遍
}
}
/*此处判断单双击的情况仍然存在较大缺陷,因为在每次触发双击事件的同时会触发单击事件.
所以我目前有一个修改的想法,不使用系统提供的e.getClickCount()方法.
可以考虑当第一次单击鼠标的时候让鼠标单击事件延时0.2秒执行,而在这段时间里等待第二次单击,
如果有第二次单击,那么我们执行双击事件任务,取消单击任务;
如果在这段时间没有等到再次单击,那么执行单击任务
由于对java延时函数的掌握不够深入,暂时没有办法完成,在此留下一个思路
*/
@Override
public void paint(Graphics g) {
super.paint(g);
Iterator iterator = points.iterator();
if(mc == 1) {
while (iterator.hasNext()){
MyPoint mypoint = (MyPoint) iterator.next();
if (mypoint.button == MouseEvent.BUTTON1) { //点击鼠标左键的情况
g.setColor(Color.GREEN);
g.fillOval(mypoint.x, mypoint.y, 40, 40);
}
if (mypoint.button == MouseEvent.BUTTON3) { //点击鼠标右键的情况
g.setColor(Color.RED);
g.fillRect(mypoint.x, mypoint.y, 40, 40);
}
}
}
else if(mc == 2){ //双击则清除此前所有点击的点
points.clear();
}
}
/*
此处同样可以调用point.get()方法来进行遍历集合
if(mc == 1) {
for(int i = 0; i < points.size(); i++){
if (points.get(i).button == MouseEvent.BUTTON1) { //点击鼠标左键的情况
g.setColor(Color.GREEN);
g.fillOval(points.get(i).x, points.get(i).y, 40, 40);
}
if (points.get(i).button == MouseEvent.BUTTON3) { //点击鼠标右键的情况
g.setColor(Color.RED);
g.fillRect(points.get(i).x, points.get(i).y, 40, 40);
}
}
需要注意的是,如果调用paint.get()来进行遍历,定义ArrayList时需要改成 ArrayList<MyPoint> points;
*/
class MyPoint { //自定义MyPoint类来记录每个点的坐标及左右键情况
int x, y, button;
public MyPoint(int x, int y, int button){
this.x = x;
this.y = y;
this.button = button;
}
}
}
这里除了使用iterator迭代器以外,同样可以使用arraylist类里的get()方法来遍历每一个元素
需要注意的是,如果调用paint.get()来进行遍历,定义ArrayList时需要改成 ArrayList<MyPoint> points;
if(mc == 1) {
for(int i = 0; i < points.size(); i++){
if (points.get(i).button == MouseEvent.BUTTON1) { //点击鼠标左键的情况
g.setColor(Color.GREEN);
g.fillOval(points.get(i).x, points.get(i).y, 40, 40);
}
if (points.get(i).button == MouseEvent.BUTTON3) { //点击鼠标右键的情况
g.setColor(Color.RED);
g.fillRect(points.get(i).x, points.get(i).y, 40, 40);
}
}
同样,由于本人的水平有限,此处判断单双击的情况仍然存在较大缺陷,因为在每次触发双击事件的同时会触发单击事件.
所以我目前有一个修改的想法,不使用系统提供的e.getClickCount()方法.
可以考虑当第一次单击鼠标的时候让鼠标单击事件延时0.2秒执行,而在这段时间里等待第二次单击,
如果有第二次单击,那么我们执行双击事件任务,取消单击任务;
如果在这段时间没有等到再次单击,那么执行单击任务;
由于对java延时函数的掌握不够深入,暂时没有办法完成,在此希望有大佬求教!
本题同样也还有一些其他解法供参考:(以下附上同学的做法)