详解Java图形化编程中的鼠标事件设计
鼠标事件的事件源往往与容器相关,当鼠标进入容器、离开容器,或者在容器中单击鼠标、拖动鼠标时都会发生鼠标事件。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(MouseEvente);
(2)mouseReleased(MouseEvente);
(3)mouseEntered(MouseEvente);
(4)mouseExited(MouseEvente);
(5)mouseClicked(MouseEvente);
【例】小应用程序设置了一个文本区,用于记录一系列鼠标事件。当鼠标进入小应用程序窗口时,文本区显示“鼠标进来”;当鼠标离开窗口时,文本区显示“鼠标走开”;当鼠标被按下时,文本区显示“鼠标按下”,当鼠标被双击时,文本区显示“鼠标双击”;并显示鼠标的坐标。程序还显示一个红色的圆,当点击鼠标时,圆的半径会不断地变大。
importjava.applet.*; importjavax.swing.*; importjava.awt.*; importjava.awt.event.*; classMyPanelextendsJPanel{ publicvoidprint(intr){ Graphicsg=getGraphics(); g.clearRect(0,0,this.getWidth(),this.getHeight()); g.setColor(Color.red); g.fillOval(10,10,r,r); } } classMyWindowextendsJFrameimplementsMouseListener{ JTextAreatext; MyPanelpanel; intx,y,r=10; intmouseFlg=0; staticStringmouseStates[]={"鼠标键按下","鼠标松开","鼠标进来","鼠标走开","鼠标双击"}; MyWindow(Strings){ super(s); Containercon=this.getContentPane(); con.setLayout(newGridLayout(2,1)); this.setSize(200,300); this.setLocation(100,100); panel=newMyPanel(); con.add(panel); text=newJTextArea(10,20); text.setBackground(Color.blue); con.add(text); addMouseListener(this); this.setVisible(true); this.pack(); } publicvoidpaint(Graphicsg){ r=r+4; if(r>80){ r=10; } text.append(mouseStates[mouseFlg]+"了,位置是:"+x+","+y+"\n"); panel.print(r); } publicvoidmousePressed(MouseEvente){ x=e.getX(); y=e.getY(); mouseFlg=0; repaint(); } publicvoidmouseRelease(MouseEvente){ x=e.getX(); y=e.getY(); mouseFlg=1; repaint(); } publicvoidmouseEntered(MouseEvente){ x=e.getX(); y=e.getY(); mouseFlg=2; repaint(); } publicvoidmouseExited(MouseEvente){ x=e.getX(); y=e.getY(); mouseFlg=3; repaint(); } publicvoidmouseClicked(MouseEvente){ if(e.getClickCount()==2){ x=e.getX(); y=e.getY(); mouseFlg=4; repaint(); } else{} } } publicclassExample6_8extendsApplet{ publicvoidinit(){ MyWindowmyWnd=newMyWindow("鼠标事件示意程序"); } }
任何组件上都可以发生鼠标事件:鼠标进入、鼠标退出、按下鼠标等。例如,在上述程序中添加一个按钮,并给按钮对象添加鼠标监视器,将上述程序中的init()方法修改成如下形式,即能示意按钮上的所有鼠标事件。
JButtonbutton; publicvoidinit(){ button=newJButton(“按钮也能发生鼠标事件”); r=10; text=newJTextArea(15,20); add(button); add(text); button.addMouseListener(this); }
如果程序希望进一步知道按下或点击的是鼠标左键或右键,鼠标的左键或右键可用InputEvent类中的常量BUTTON1_MASK和BUTTON3_MASK来判定。例如,以下表达式判断是否按下或点击了鼠标右键:
e.getModifiers()==InputEvent.BUTTON3_MASK
MouseMotionListener接口
MouseMotionListener接口处理拖动鼠标和鼠标移动两种事件。
注册监视器的方法是:
addMouseMotionListener(监视器)
要实现的的接口方法有两个:
(1)mouseDragged(MouseEvente)
(2)mouseMoved(MouseEvente)
【例】一个滚动条与显示窗口同步变化的应用程序。窗口有一个方块,用鼠标拖运方块,或用鼠标点击窗口,方块改变显示位置,相应水平和垂直滚动条的滑块也会改变它们在滚动条中的位置。反之,移动滚动条的滑块,方块在窗口中的显示位置也会改变。
importjavax.swing.*; importjava.awt.*; importjava.awt.event.*; classMyWindowextendsJFrame{ publicMyWindow(Strings){ super(s); Containercon=this.getContentPane(); con.setLayout(newBorderLayout()); this.setLocation(100,100); JScrollBarxAxis=newJScrollBar(JScrollBar.HORIZONTAL,50,1,0,100); jScrollBaryAxis=newjScrollBar(JScrollBar.VERTICAL,50,1,0,100); MyListenerlistener=newMyListener(xAxis,yAxis,238,118); JpanelscrolledCanvas=newJPanel(); scrolledCanvas.setLayout(newBorderLayout()); 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(); } publicDimensiongetPreferredSize(){ returnnewDimension(500,300); } } classMyListenerextendsJComponentimplementsMouseListener,MouseMotionListener,AdjustmentListener{ privateintx,y; privateJScrollBarxScrollBar; privateJScrollBaryScrollBar; privatevoidupdateScrollBars(intx,inty){ intd; d=(int)(((float)x/(float)getSize().width)*100.0); xScrollBar.setValue(d); d=(int)(((float)y/(float)getSize().height)*100.0); yScrollBar.setValue(d); } publicMyListener(JScrollBarxaxis,JScrollBaryaxis,intx0,inty0){ xScrollBar=xaxis; yScrollBar=yaxis; x=x0; y=y0; xScrollBar.addAdjustmentListener(this); yScrollBar.addAdjustmentListener(this); this.addMouseListener(this); this.addMouseMotionListener(this); } publicvoidpaint(Graphicsg){ g.setColor(getBackground()); Dimensionsize=getSize(); g.fillRect(0,0,size.width,size.height); g.setColor(Color.blue); g.fillRect(x,y,50,50); } publicvoidmouseEntered(MouseEvente){} publicvoidmouseExited(MouseEvente){} publicvoidmouseClicked(MouseEvente){} publicvoidmouseRelease(MouseEvente){} publicvoidmouseMoved(MouseEvente){} publicvoidmousePressed(MouseEvente){ x=e.getX(); y=e.getY(); updateScrollBars(x,y); repaint(); } publicvoidmouseDragged(MouseEvente){ x=e.getX(); y=e.getY(); updateScrollBars(x,y); repaint(); } publicvoidadjustmentValueChanged(AdjustmentEvente){ if(e.getSource()==xScrollBar) x=(int)((float)(xScrollBar.getValue()/100.0)*getSize().width); elseif(e.getSource()==yScrollBar) y=(int)((float)(yScrollBar.getValue()/100.0)*getSize().height); repaint(); } } publicclassExample6_9{ publicstaticvoidmain(){ MyWindowmyWindow=newMyWindow("滚动条示意程序"); } }
上述例子中,如果只要求通过滑动滑块,改变内容的显示位置,可以简单地使用滚动面板JScrollPane。如果是这样,关于滚动条的创建和控制都可以免去,直接由JScrollPane内部实现。参见以下修改后的MyWindow的定义:
classMyWindowextendsJFrame{ publicMyWindow(Strings){ super(s); Containercon=this.getContentPane(); con.setLayout(newBorderLayout()); this.setLocaltion(100,100); MyListenerlistener=newMyListener(); listener.setPreferredSize(newDimension(700,700)); JScrollPanescrolledCanvas=newJScrollPane(listener); this.add(scrolledCanvas,BorderLayout.CENTER); this.setVisible(true); this.pack(); } publicDimensiongetPreferredSize(){ returnnewDimension(400,400); } }
鼠标指针形状也能由程序控制,setCursor()方法能设置鼠标指针形状。例如,代码setCursor(Cursor.getPredefinedCursor(cursor.WAIT_CURSOR))。