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

 更新时间:2015年10月08日 17:32:44   投稿:goldensun  
这篇文章主要介绍了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))。

相关文章

  • java eclipse 出现 xxx cannot be resolved to a type 错误解决方法

    java eclipse 出现 xxx cannot be resolved to a type 错误解决方法

    这篇文章主要介绍了java eclipse 出现 xxx cannot be resolved to a type 错误解决方法的相关资料,需要的朋友可以参考下
    2017-03-03
  • Idea 解决 Could not autowire. No beans of ''xxxx'' type found 的错误提示

    Idea 解决 Could not autowire. No beans of ''xxxx'' type found

    这篇文章主要介绍了Idea 解决 Could not autowire. No beans of 'xxxx' type found 的错误提示,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • 解决BeanUtils.copyProperties之大坑

    解决BeanUtils.copyProperties之大坑

    这篇文章主要介绍了解决BeanUtils.copyProperties之大坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 使用JPA自定义id策略避免主键自增

    使用JPA自定义id策略避免主键自增

    这篇文章主要介绍了使用JPA自定义id策略避免主键自增问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Spring Security在标准登录表单中添加一个额外的字段

    Spring Security在标准登录表单中添加一个额外的字段

    这篇文章主要介绍了Spring Security在标准登录表单中添加一个额外的字段,我们将重点关注两种不同的方法,以展示框架的多功能性以及我们可以使用它的灵活方式。 需要的朋友可以参考下
    2019-05-05
  • 使用ShardingJDBC进行数据分片以及读写分离

    使用ShardingJDBC进行数据分片以及读写分离

    ShardingJDBC是一个轻量级的Java框架,提供了数据分片、读写分离、分布式主键生成等数据访问功能,本文将给大家介绍如何使用ShardingJDBC进行数据分片以及读写分离,需要的朋友可以参考下
    2024-01-01
  • java中Servlet监听器的工作原理及示例详解

    java中Servlet监听器的工作原理及示例详解

    这篇文章主要介绍了java中Servlet监听器的工作原理及示例详解。Servlet监听器用于监听一些重要事件的发生,监听器对象可以在事情发生前、发生后可以做一些必要的处理。感兴趣的可以来了解一下
    2020-07-07
  • Springboot项目实现Mysql多数据源切换的完整实例

    Springboot项目实现Mysql多数据源切换的完整实例

    这篇文章主要给大家介绍了关于Springboot项目实现Mysql多数据源切换的完整实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Java安全后端返回文件流方式

    Java安全后端返回文件流方式

    这篇文章主要介绍了Java安全后端返回文件流方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • SpringBoot注解@ConditionalOnClass底层源码实现

    SpringBoot注解@ConditionalOnClass底层源码实现

    这篇文章主要为大家介绍了SpringBoot注解@ConditionalOnClass底层源码实现,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02

最新评论