首页 > 编程语言 >《Java核心技术 卷I》用户图形界面鼠标事件

《Java核心技术 卷I》用户图形界面鼠标事件

时间:2024-11-15 14:48:41浏览次数:3  
标签:current Java 鼠标 java 图形界面 CURSOR import public

鼠标事件

        如果只希望用户能够点击按钮或菜单,那么就不需要显式地处理鼠标事件,鼠标操作将由用户界面中的各种组件内部处理,不过,如果希望用户能使用鼠标画图,就需要捕获鼠标移动,点击和拖动事件。

本节,我们将展示一个简单的图形编辑器应用,它允许用户在画布上放置、移动和擦除方块。

        用户点击鼠标按钮时,将会调用三个监听器方法:鼠标第一次被按下时调用mousePressed,鼠标被释放时调用mouseReleased,最后调用mouseClicked,如果只对最终的点击事件感兴趣,就可以忽略前两个方法,以MouseEvent类对象作为参数,调用getX和getY方法可以获得鼠标被按下时鼠标指针所在的x和y坐标,想要区分单击,双击和三击,需要使用getClickCount方法。

        鼠标在窗口移动时,窗口会收到一连串的鼠标移动事件,有两个独立的接口MouseListener和MouseMotionListener,这样做有利于提高效率,当用户移动鼠标时,会有大量鼠标事件,只关心鼠标点击(click)的监听器就不会被多余的鼠标移动事件所干扰。

        这里给出测试程序将捕获鼠标动作事件,光标位于一个小方块之上时变成另一种形状(十字),这是使用Cursor类中的getPredefinedCursor方法完成的,以下列出了在Windows环境下这个方法使用常量以及相应的光标形状。

常量为:

常量

DEFAULT_CURSOR

NE_RESIZE_CURSOR

CROSSHAIR_CURSOR

E_RESIZE_CURSOR

HAND_CURSOR

SE_RESIZE_CURSOR

MOVE_CURSOR

S_RESIZE_CURSOR

TEXT_CURSOR

SW_RESIZE_CURSOR

WAIT_CURSOR

W_RESIZE_CURSOR

N_RESIZE_CURSOR

NW_RESIZE_CURSOR

MouseMotionListener类的mouseMoved方法:

public void mouseMoved(MouseEvent event){
    if(find(event.getPoint())==null){
        setCursor(Cursor.getDefaultCursor());    
    }else{
         setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));       
    }
}

        如果用户在移动鼠标的同时按下鼠标,就会生成mouseDragged调用而不是mouseMoved调用。在测试 应用中,用户可以拖动光标下的小方块,我们只是更新当前拖动的方块,让它在鼠标位置居中,然后,重新绘制画布,以显示新的鼠标位置。

        还有另外两个鼠标事件方法:mouseEnterd和mouseExited,这两个方法会在鼠标进入或移除组件时被调用,监听鼠标点击事件,mouseClicked。

案例:点击鼠标新建小方块,可拖动方块,双击删除方块

package mouse;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class MouseComponent extends JComponent {
    
    public static void main(String[] args) {
        EventQueue.invokeLater(()->{
            var frame = new JFrame();
            frame.add(new MouseComponent());
            frame.pack();
            frame.setTitle("鼠标事件");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
    
    private static final int DEFAULT_WIDTH = 300;
    private static final int DEFAULT_HEIGHT = 200;
    
    private static final int SIDELENGTH = 10;//边长10
    private ArrayList<Rectangle2D> squares;
    private Rectangle2D current;//这个正方形包含了鼠标的指针
    
    public MouseComponent() {
        squares = new ArrayList<>();
        current = null;
        addMouseListener(new MouseHandler());
        addMouseMotionListener(new MouseMotionHandler());
    }
    
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        var g2 = (Graphics2D)g;
        //画所有的正方形
        for (Rectangle2D r : squares) {
            g2.draw(r);
        }
    }
    
    public Rectangle2D find(Point2D p) {
        for (Rectangle2D r : squares) {
            if (r.contains(p)) return r;
        }
        return null;
    }
    
    public void add(Point2D p) {
        double x = p.getX();
        double y = p.getY();
        current = new Rectangle2D.Double(x-SIDELENGTH/2,y-SIDELENGTH/2,SIDELENGTH,SIDELENGTH);
        squares.add(current);
        repaint();
    }
    
    public void remove(Rectangle2D s) {
        if(s == null) return;
        if(s == current) current = null;
        squares.remove(s);
        repaint();
    }
    
    private class MouseHandler extends MouseAdapter {
        @Override
        public void mousePressed(MouseEvent e) {
            current = find(e.getPoint());
            if(current==null) add(e.getPoint());
        }
        @Override
        public void mouseClicked(MouseEvent e) {
            current = find(e.getPoint());
            if(current!=null&&e.getClickCount()>=2) remove(current);
        }
    }
    
    private class MouseMotionHandler implements MouseMotionListener {

        @Override
        public void mouseMoved(MouseEvent e) {
            if(find(e.getPoint())==null) setCursor(Cursor.getDefaultCursor());
            else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if(current!=null) {
                int x = e.getX();
                int y = e.getY();
                current.setFrame(x-SIDELENGTH/2,y-SIDELENGTH/2,SIDELENGTH,SIDELENGTH);
                repaint();
            }
        }
        
    }

}

java.awt.event.MouseEvent 1.1

  • int getX()
  • int getY()
  • Point getPoint(),返回事件发生时点(鼠标点击位置)相对于事件源组件的左上角x和y坐标。
  • int getClickCount(),返回与事件相关的鼠标连击次数(连击时间与系统有关)。

java.awt.Component 1.0

  • public void setCursor(Cursor cursor),为指定光标设置光标图像。

标签:current,Java,鼠标,java,图形界面,CURSOR,import,public
From: https://blog.csdn.net/qq_36324341/article/details/143799393

相关文章

  • 《Java核心技术 卷I》图形界面事件处理适配器类
    适配器类并不是所有的事件处理都像按钮点击那样简单,假设你想监视用户何时想要关闭主窗体,可能希望弹出一个对话框,只有在用户确认之后才退出程序。当程序试图关闭一个窗口时,JFrame对象就是WindowEvent的事件源,如果希望捕获这个事件,就必须有一个合适的监听器对象,并将它添加到窗体......
  • 如何用Java爬虫精准获取商品历史价格信息
    在数字化时代,商品价格信息的获取变得尤为重要。对于消费者来说,了解商品的历史价格趋势可以帮助他们做出更明智的购买决策。而对于商家来说,掌握价格数据则有助于制定更有效的销售策略。本文将详细介绍如何使用Java编写爬虫程序,精准获取商品的历史价格信息以及API数据。Java爬虫......
  • java代码练习:银行管理系统
    packageTestFirst;importjava.util.Arrays;importjava.util.Objects;importjava.util.Scanner;publicclassTestBank{publicstaticvoidmain(String[]args){Bankbank=newBank();bank.login();}}classBank{Scannerinput=newS......
  • java处理excel文件
    文章目录maven引入依赖编写ExcelUtil工具类使用ExcelUtil工具类maven引入依赖<!--处理excel依赖--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version></dependency><......
  • Java虚拟机(JVM):Java程序的心脏
    Java虚拟机(JavaVirtualMachine,JVM)是Java运行时环境的核心组件,它不仅为Java程序提供了跨平台的能力,还负责内存管理、类加载、字节码解释与执行等重要功能。本文将深入探讨JVM的架构、内存划分、工作原理以及性能调优等方面的内容,帮助读者全面理解这一关键技术。一、JVM的架构......
  • Java集合框架之Collection集合遍历
    引言在Java编程中,集合(Collection)框架是处理对象集合的核心工具。它提供了一套统一的接口和类来存储和操作对象集合。遍历集合是日常开发中的一项基本任务,本文将深入探讨JavaCollection集合的遍历方法,并提供实际的代码示例。JavaCollection框架概览JavaCollection框架主要......
  • 最全JAVA面试八股文,终于整理完了
    1、Java线程具有五中基本状态(1)新建状态(New):当线程对象对创建后,即进入了新建状态,如:Threadt=newMyThread();(2)就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是......
  • java请求频次控制
    1、添加工具类importjava.util.concurrent.atomic.AtomicInteger;/***频次调用控制类*/publicclassRateLimiterUtil{privatefinalAtomicIntegersum;privatefinalintmaxRequests;privatelongperiod=1000;//1秒privatelonglastTime......
  • 2024 年 Java 面试最全攻略:程序员求职跳槽必刷题目 1000+,横扫一切技术盲点!
    写在前面马上又要到收割Offer的季节,你准备好了吗?曾经的我,横扫各个大厂的Offer。还是那句话:进大厂临时抱佛脚是肯定不行的,一定要注重平时的总结和积累,多思考,多积累,多总结,多复盘,将工作经历真正转化为自己的工作经验。面经分享今天给大家分享一个面试大厂的完整面经,小伙......
  • 如何准备Java面试?
    今年招聘高峰期已过,不知道大家都找到工作没有。反正我最近是收到很多粉丝的私信说自己投了简历却杳无音信,在第一关就败下阵来。言归正传出现这一情况要么就是你的简历没有修饰好,要么就是你简历上掌握的技术栈还不足以满足你投的岗位的需求,当然后者是需要平时积累。一般像我们......