热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

详解Java图形化编程中的鼠标事件设计

这篇文章主要介绍了Java图形化编程中的鼠标事件设计,是Java的GUI开发中的基础部分,需要的朋友可以参考下

鼠标事件的事件源往往与容器相关,当鼠标进入容器、离开容器,或者在容器中单击鼠标、拖动鼠标时都会发生鼠标事件。java语言为处理鼠标事件提供两个接口:MouseListener,MouseMotionListener接口。
MouseListener接口

MouseListener接口能处理5种鼠标事件:按下鼠标,释放鼠标,点击鼠标、鼠标进入、鼠标退出。相应的方法有:
(1) getX():鼠标的X坐标
(2) getY():鼠标的Y坐标
(3) getModifiers():获取鼠标的左键或右键。
(4) getClickCount():鼠标被点击的次数。
(5) getSource():获取发生鼠标的事件源。
(6) addMouseListener(监视器):加放监视器。
(7) removeMouseListener(监视器):移去监视器。

要实现的MouseListener接口的方法有:
(1) mousePressed(MouseEvent e);
(2) mouseReleased(MouseEvent e);
(3) mouseEntered(MouseEvent e);
(4) mouseExited(MouseEvent e);
(5) mouseClicked(MouseEvent e);

【例】小应用程序设置了一个文本区,用于记录一系列鼠标事件。当鼠标进入小应用程序窗口时,文本区显示“鼠标进来”;当鼠标离开 窗口时,文本区显示“鼠标走开”;当鼠标被按下时,文本区显示“鼠标按下”,当鼠标被双击时,文本区显示“鼠标双击”;并显示鼠标的坐标。程序还显示一个红色的圆,当点击鼠标时,圆的半径会不断地变大。

import java.applet.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyPanel extends JPanel{
  public void print(int r){
    Graphics g = getGraphics();
    g.clearRect(0,0,this.getWidth(),this.getHeight());
    g.setColor(Color.red);
    g.fillOval(10,10,r,r);
  }
}
class MyWindow extends JFrame implements MouseListener{
  JTextArea text;
  MyPanel panel;
  int x,y,r =10;
  int mouseFlg=0;
  static String mouseStates[]={"鼠标键按下","鼠标松开","鼠标进来","鼠标走开","鼠标双击"};
  MyWindow(String s){
    super(s);
    Container con = this.getContentPane();
    con.setLayout(new GridLayout(2,1));
    this.setSize(200,300);
    this.setLocation(100,100);
    panel = new MyPanel();
    con.add(panel);
    text = new JTextArea(10,20);
    text.setBackground(Color.blue);
    con.add(text);
    addMouseListener(this);
    this.setVisible(true);
    this.pack();
  }
  public void paint(Graphics g){
    r = r+4;
    if(r>80){
      r=10;
    }
    text.append(mouseStates[mouseFlg]+"了,位置是:" +x+","+y+"\n");
    panel.print(r);
  }
  public void mousePressed(MouseEvent e){
    x = e.getX();
    y = e.getY();
    mouseFlg = 0;
    repaint();
  }
  public void mouseRelease(MouseEvent e){
    x = e.getX();
    y = e.getY();
    mouseFlg = 1;
    repaint();
  }
  public void mouseEntered(MouseEvent e){
    x = e.getX();
    y = e.getY();
    mouseFlg = 2;
    repaint();
  }
  public void mouseExited(MouseEvent e){
    x = e.getX();
    y = e.getY();
    mouseFlg = 3;
    repaint();
  }
  public void mouseClicked(MouseEvent e){
    if(e.getClickCount()==2){
      x = e.getX();
      y = e.getY();
      mouseFlg = 4;
      repaint();
    }
    else{}
  }
}
public class Example6_8 extends Applet{
  public void init(){
    MyWindow myWnd = new MyWindow("鼠标事件示意程序");
  }
}

任何组件上都可以发生鼠标事件:鼠标进入、鼠标退出、按下鼠标等。例如,在上述程序中添加一个按钮,并给按钮对象添加鼠标监视器,将上述程序中的init()方法修改成如下形式,即能示意按钮上的所有鼠标事件。

JButton button;
public void init(){
  button = new JButton(“按钮也能发生鼠标事件”);
  r = 10;
  text = new JTextArea(15,20);
  add(button);
  add(text);
  button.addMouseListener(this);
}

如果程序希望进一步知道按下或点击的是鼠标左键或右键,鼠标的左键或右键可用InputEvent类中的常量BUTTON1_MASK和BUTTON3_MASK来判定。例如,以下表达式判断是否按下或点击了鼠标右键:

  e.getModifiers()==InputEvent. BUTTON3_MASK


MouseMotionListener接口

MouseMotionListener接口处理拖动鼠标和鼠标移动两种事件。

注册监视器的方法是:
    addMouseMotionListener(监视器)
要实现的的接口方法有两个:
(1) mouseDragged(MouseEvent e)
(2) mouseMoved(MouseEvent e)

【例】一个滚动条与显示窗口同步变化的应用程序。窗口有一个方块,用鼠标拖运方块,或用鼠标点击窗口,方块改变显示位置,相应水平和垂直滚动条的滑块也会改变它们在滚动条中的位置。反之,移动滚动条的滑块,方块在窗口中的显示位置也会改变。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class MyWindow extends JFrame{
  public MyWindow(String s){
    super(s);
    Container con = this.getContentPane();
    con.setLayout(new BorderLayout());
    this.setLocation(100,100);
    JScrollBar xAxis = new JScrollBar(JScrollBar.HORIZONTAL,50,1,0,100);
    jScrollBar yAxis = new jScrollBar(JScrollBar.VERTICAL,50,1,0,100);
    MyListener listener = new MyListener(xAxis,yAxis,238,118);
    Jpanel scrolledCanvas = new JPanel();
    scrolledCanvas.setLayout(new BorderLayout());
    scrolledCanvas.add(listener,BorderLayout.CENTER);
    scrolledCanvas.add(xAix,BorderLayout.SOUTH);
    scrolledCanvas.add(yAix,BorderLayout.EAST);
    con.add(scrolledCanvas,BorderLayout.NORTH);
    this.setVisible(true);
    this.pack();
  }
  public Dimension getPreferredSize(){
    return new Dimension(500,300);
  }
}
class MyListener extends JComponent implements MouseListener, MouseMotionListener,AdjustmentListener{
  private int x,y;
  private JScrollBar xScrollBar;
  private JScrollBar yScrollBar;
  private void updateScrollBars(int x,int y){
    int d;
    d = (int)(((float)x/(float)getSize().width)*100.0);
    xScrollBar.setValue(d);
    d = (int)(((float)y/(float)getSize().height)*100.0);
    yScrollBar.setValue(d);
  }
  public MyListener(JScrollBar xaxis,JScrollBar yaxis,int x0,int y0){
    xScrollBar =xaxis;
    yScrollBar =yaxis;
    x = x0;
    y=y0;
    xScrollBar.addAdjustmentListener(this);
    yScrollBar.addAdjustmentListener(this);
    this.addMouseListener(this);
    this.addMouseMotionListener(this);
  }
  public void paint(Graphics g){
    g.setColor(getBackground());
    Dimension size = getSize();
    g.fillRect(0,0,size.width,size.height);
    g.setColor(Color.blue);
    g.fillRect(x,y,50,50);
  }
  public void mouseEntered(MouseEvent e){}
  public void mouseExited(MouseEvent e){}
  public void mouseClicked(MouseEvent e){}
  public void mouseRelease(MouseEvent e){}
  public void mouseMoved(MouseEvent e){}
  public void mousePressed(MouseEvent e){
    x = e.getX();
    y = e.getY();
    updateScrollBars(x,y);
    repaint();
  }
  public void mouseDragged(MouseEvent e){
    x = e.getX();
    y = e.getY();
    updateScrollBars(x,y);
    repaint();
  }
  public void adjustmentValueChanged(AdjustmentEvent e){
    if(e.getSource()==xScrollBar)
      x=(int)((float)(xScrollBar.getValue()/100.0)*getSize().width);
    else if(e.getSource()==yScrollBar)
      y = (int)((float)(yScrollBar.getValue()/100.0)*getSize().height);
    repaint();
  }
}
public class Example6_9{
  public static void main(){
    MyWindow myWindow = new MyWindow("滚动条示意程序");
  }
}

上述例子中,如果只要求通过滑动滑块,改变内容的显示位置,可以简单地使用滚动面板JScrollPane。如果是这样,关于滚动条的创建和控制都可以免去,直接由JScrollPane内部实现。参见以下修改后的MyWindow的定义:

class MyWindow extends JFrame{
  public MyWindow(String s){
    super(s);
    Container con = this.getContentPane();
    con.setLayout(new BorderLayout());
    this.setLocaltion(100,100);
    MyListener listener = new MyListener();
    listener.setPreferredSize(new Dimension(700,700));
    JScrollPane scrolledCanvas = new JScrollPane(listener);
    this.add(scrolledCanvas,BorderLayout.CENTER);
    this.setVisible(true);
    this.pack();
  }
  public Dimension getPreferredSize(){
    return new Dimension(400,400);
  }
}

鼠标指针形状也能由程序控制 ,setCursor()方法能设置鼠标指针形状。例如,代码setCursor(Cursor.getPredefinedCursor(cursor.WAIT_CURSOR))。


推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 标题: ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 本文介绍了在Docker容器技术中限制容器对CPU的使用的方法,包括使用-c参数设置容器的内存限额,以及通过设置工作线程数量来充分利用CPU资源。同时,还介绍了容器权重分配的情况,以及如何通过top命令查看容器在CPU资源紧张情况下的使用情况。 ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • position属性absolute与relative的区别和用法详解
    本文详细解读了CSS中的position属性absolute和relative的区别和用法。通过解释绝对定位和相对定位的含义,以及配合TOP、RIGHT、BOTTOM、LEFT进行定位的方式,说明了它们的特性和能够实现的效果。同时指出了在网页居中时使用Absolute可能会出错的原因,即以浏览器左上角为原始点进行定位,不会随着分辨率的变化而变化位置。最后总结了一些使用这两个属性的技巧。 ... [详细]
  • 开发笔记:Docker 上安装启动 MySQL
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Docker上安装启动MySQL相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 本文介绍了Java的公式汇总及相关知识,包括定义变量的语法格式、类型转换公式、三元表达式、定义新的实例的格式、引用类型的方法以及数组静态初始化等内容。希望对读者有一定的参考价值。 ... [详细]
  • 本文讨论了微软的STL容器类是否线程安全。根据MSDN的回答,STL容器类包括vector、deque、list、queue、stack、priority_queue、valarray、map、hash_map、multimap、hash_multimap、set、hash_set、multiset、hash_multiset、basic_string和bitset。对于单个对象来说,多个线程同时读取是安全的。但如果一个线程正在写入一个对象,那么所有的读写操作都需要进行同步。 ... [详细]
  • 本文介绍了一种图片处理应用,通过固定容器来实现缩略图的功能。该方法可以实现等比例缩略、扩容填充和裁剪等操作。详细的实现步骤和代码示例在正文中给出。 ... [详细]
  • C++语言入门:数组的基本知识和应用领域
    本文介绍了C++语言的基本知识和应用领域,包括C++语言与Python语言的区别、C++语言的结构化特点、关键字和控制语句的使用、运算符的种类和表达式的灵活性、各种数据类型的运算以及指针概念的引入。同时,还探讨了C++语言在代码效率方面的优势和与汇编语言的比较。对于想要学习C++语言的初学者来说,本文提供了一个简洁而全面的入门指南。 ... [详细]
author-avatar
Aero-Maxwell
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有