详解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(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))。