java笔记 MouseListener 与 MouseMotionListener

一.鼠标点击事件 MouseListener

这个接口MouseListener总共有五个函数
1.mousePressed(MouseEvent e) 按下触发事件
2.mouseReleased(MouseEvent e) 释放触发事件
3.mouseEntered(MouseEvent e) 进入组件触发事件
4.mouseExited(MouseEvent e) 离开组件触发事件
5.mouseClicked(MouseEvent e) 单击触发事件


还有MouseEvent的5个方法(不需要覆盖)
1.getX() 获取x坐标
2.getY() 获取yzuob
3.getButton() 获取左键或右键,左键MouseEvent.Button1,右键MouseEvent.Button3
4.getCickCount() 获取点击次数
5.getSource() 获取鼠标的事件源,返回值是对象,为组建的子类

//Inner class 事件处理例一
import java.awt.*;
import java.awt.event.*;
import java.net.PortUnreachableException;
import java.rmi.MarshalledObject;
import javax.swing.*;

class WindowMouse extends JFrame
{
    JTextField text;
    JButton button;
    JTextArea textArea;
    MousePolice police;  // 鼠标事件监听器

    WindowMouse(String s)
    {
        init(s);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    void init(String s)
    {
        setTitle(s);
        setBounds(10,10,460,360);
        setLayout(new FlowLayout());
        text = new JTextField(8);
        textArea = new JTextArea(5,28);
        police = new MousePolice();

        police.setJTextArea(textArea); // 与文本框建立连接
        text.addMouseListener(police);

        button = new JButton("按钮");
        button.addMouseListener(police);

        add(button);
        add(text);
        add(new JScrollPane(textArea));  // 带滚动条的面板

    }

    private class MousePolice implements MouseListener
    {
        JTextArea area;

        public void setJTextArea(JTextArea area){this.area = area;}

        // 实现接口函数
        // 按下获取位置
        public void mousePressed(MouseEvent e)
        {
            area.append("\n鼠标按下,位置: " + e.getX() + " ," + e.getY());
        }

        // 释放获取位置
        public void mouseReleased(MouseEvent e)
        {
            area.append("\n鼠标释放,位置: " + e.getX() + " ," + e.getY());
        }

        // 鼠标进入组件事件
        public void mouseEntered(MouseEvent e)
        {
            if(e.getSource() instanceof JButton) // 进入按钮,getsource返回对象
                area.append("\n鼠标进入按钮");
            if(e.getSource() instanceof JTextField) // 进入按钮
                area.append("\n鼠标进入文本框");
            if(e.getSource() instanceof JFrame) // 进入按钮
                area.append("\n鼠标进入窗口");
        }

        public void mouseExited(MouseEvent e)  // 鼠标退出组件
        {
            area.append("\n鼠标退出,位置: \" + e.getX() + \" ,\" + e.getY()");
        }

        public void mouseClicked(MouseEvent e)
        {
            if(e.getClickCount() >= 2)
                area.append("\n鼠标连击");
            else if(e.getButton() == e.BUTTON1)
                area.append("\n鼠标左键");
            else if(e.getButton() == e.BUTTON2)
                area.append("\n鼠标中键");
            else if(e.getButton() == e.BUTTON3)
                area.append("\n鼠标右键");
        }

    }
}

//主类
public class test
{
    public static void main(String args[])
    {
        WindowMouse win = new WindowMouse("鼠标事件");
    }
}

在这里插入图片描述

在这里插入图片描述

二.鼠标拖动事件 MouseMotionListener

这类的参数也还是MouseEvent
实现接口中的两个方法mouseDragged(MouseEvent e)mouseMoved(MouseEvent e)

//Inner class 事件处理例一
import java.awt.*;
import java.awt.event.*;
import java.net.PortUnreachableException;
import java.rmi.MarshalledObject;
import javax.swing.*;

class WindowMove extends JFrame
{
    LP layeredpane;  // 面板类,同时实现监听器接口

    WindowMove(String s)
    {
        layeredpane = new LP();
        add(layeredpane, BorderLayout.CENTER);

        setVisible(true);
        setTitle(s);
        setBounds(10, 10, 460, 360);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }



    // 创建鼠标移动监听器
    // 继承了 JLayeredPane 类,这是个分层的面板
    private class LP extends JLayeredPane implements MouseListener, MouseMotionListener
    {
        JButton button;
        int x, y, a, b, x0, y0;

        // 初始化监听器
        LP()
        {
            // 创建按钮组件
            button = new JButton("别拽我");

            // 给组件注册监听器
            button.addMouseListener(this);
            button.addMouseMotionListener(this);

            setLayout(new FlowLayout());
            add(button, JLayeredPane.DEFAULT_LAYER);  // 将 button 添加到JLayeredPane 面板中,DEFAULT_LAYER 是int类,表示放在最上层

        }

        // 实现接口函数
        public void mousePressed(MouseEvent e)
        {
            JComponent com = null;  // 容器类
            com = (JComponent)e.getSource();  // 将组件的子类转化为 JComponent 类
            setLayer(com, JLayeredPane.DRAG_LAYER);  // 重新将 com 组件设置为 DRAG_LAYER 层。这里第一个参数必须是JComponent类
            a = com.getBounds().x;   // 获得组件左上角的x坐标
            b = com.getBounds().y;
            x0 = e.getX();        // 获取鼠标在事件源 (刚在组件点击下的位置) 中的位置坐标
            y0 = e.getY();
        }

        public void mouseReleased(MouseEvent e)
        {
            JComponent com = null;
            com = (JComponent)e.getSource();
            setLayer(com, JLayeredPane.DEFAULT_LAYER);
        }

        public void mouseEntered(MouseEvent e){}
        public void mouseExited(MouseEvent e){}
        public void mouseClicked(MouseEvent e){}
        public void mouseMoved(MouseEvent e){}
        public void mouseDragged(MouseEvent e)
        {
            JComponent com = null;
            if(e.getSource() instanceof Component)
            {
                com = (JComponent)e.getSource();
                a = com.getBounds().x;
                b = com.getBounds().y;
                x = e.getX();
                y = e.getY();
                a += x;  // a = a + x
                b += y;  // b = b + y
                com.setLocation(a - x0, b - y0);   // 重新设置组件的坐标
                // 在拖拽组件的时候,要利用公式 a + x - x0,b + y - y0
            }
        }
    }
}

//主类
public class test
{
    public static void main(String args[])
    {
        WindowMove win = new WindowMove("鼠标拖动事件");
    }
}

在这里插入图片描述
在这里插入图片描述
这个程序主要需要一个公式
获取鼠标指针的坐标 x, y
组件的左上角的坐标 a, b
最初鼠标在组件上按下的坐标 x0, y0

移动时,组件左上角的坐标应该是 a + x - x0, a + y - y0


另一个重要的部分是面板的选择
这里选择了 JLayeredPane面版,可以拖动组件
它利用了组件都是JComponent的子类,所以可以将组件转化为这个父类,使用setLayer(JComponent, int)来重新设置组件在这个面板中的图层位置

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值