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