逻辑基本流程:
1.在面板上画出一个小球
2.获取鼠标坐标
3.将鼠标坐标与小球坐标比较
3.1 鼠标悬浮在小球上时,面板文字显示“please click”,同时将悬浮表示markM置为true;
3.2 鼠标点击选中小球时,面板文字再显示”Bingo“,同时将选中标识markC置为true;
3.3 鼠标离开晓小球范围时,两个标识全部重新置为false;
(这个设计是为了应对这个BUG,上一次的正确选中,选中标识置为真,即使当鼠标不再停留在小球区域且未选中小球时,markC仍旧为真,与真实期望不符合;真实期望下,当鼠标离开小球区域,之前的选中也同样”无效了“,使用markC重新置false来代表”无效“;如果不这么做,我遇到的BUG就是,好了,离开小球了,但是只要你鼠标进行拖拽操作,小球就自动跳过来了,好像是隔空取物了一样...)
4.当选择标识 markC 以及 悬浮标识 markM都为真时,小球随鼠标拖拽!
完整源码:
import java.awt.*;
import java.awt.event.*;
public class MyBall
{
public static void main(String args[])
{
Frame w = new Frame();
w.setSize(300,400);
MyPanel mp = new MyPanel();
w.add(mp);
Thread t= new Thread(mp);
t.start();
//注册监听静态鼠标事件,例如:点击
w.addMouseListener(mp);
mp.addMouseListener(mp);
//注册监听动态鼠标事件,例如:拖拽
w.addMouseMotionListener(mp);
mp.addMouseMotionListener(mp);
w.show();
}
}
class MyPanel extends Panel implements Runnable,MouseListener,MouseMotionListener
{
int x;//小球的坐标
int y;
int mx;//鼠标的坐标
int my;
Boolean markC=false;//标识鼠标是否悬浮在小球之上
Boolean markM=false;//标识鼠标是否选中小球
MyPanel(){
x=(int)(Math.random()*300);
y=(int)(Math.random()*300);
}
public void paint(Graphics g){
g.fillOval(x,y,20,20);//小球坐标控制小球出现位置
g.setColor(Color.RED);
//分别显示鼠标坐标和小球坐标
g.drawString("Mouse X: "+mx+" Y: "+my,5,15);
g.drawString("Ball X: "+x+" Y: "+y,5,25);
if(markM){
g.drawString(" Please Click!",5,35);//鼠标悬浮在小球之上时显示请选中
if(markC){
g.drawString(" Bingo!",105,35);//鼠标选中小球时显示,选中了
}
}
else
{
g.drawString(" Miss!",5,35);//鼠标未选中小球且未悬浮在小球上时显示未击中
}
}
public void run(){
while(true){
try{
Thread.sleep(30);
}
catch(Exception e){}
repaint();
}
}
//@Override MouseListener
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
//鼠标点击事件
@Override
public void mouseClicked(MouseEvent e) {
mx=e.getX();
my=e.getY();
if((mx-x)<20&&(mx-x)>0&&(my-y)<20&&(my-y)>0){
markC=true;
}
else{
markC=false;
}
}
//@Override MouseMotoionListener
//鼠标移动事件
//获取鼠标坐标 进行判断 看鼠标是否悬浮在小球之上
//若鼠标悬浮在小球之上,则将markM置为true
@Override
public void mouseMoved(MouseEvent e) {
mx=e.getX();
my=e.getY();
if((mx-x)<20&&(mx-x)>0&&(my-y)<20&&(my-y)>0){
markM=true;
}
else{
markM=false;
markC=false; //当鼠标离开小球区域时,点击造成的markC重新置为false!
}
}
//鼠标拖拽事件
//当鼠标悬浮在小球之上(markM为true)且鼠标选中小球(markC为true)时
//小球坐标被赋值为鼠标坐标
//实现小球随鼠标拖拽移动的效果
@Override
public void mouseDragged(MouseEvent e) {
if(markC==true&&markM==true){
x=e.getX();
y=e.getY();
}
}
}
运行结果图:
心得:
真心就是几大块啊!不知道术语怎么讲,需要注册监听(最上面的!)、需要重写方法下面的那一系列@Override,需要(引用?还是声明)这些东西什么XXListener。
之前写的打字母用就是键盘事件,所以是KeyListener是KeyEvent,这次用的是鼠标就是MouseListener是MouseEvent 以及MouseMotionListener还是MouseEvent。