📄 jv0501.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0041)http://king.online.ha.cn/java/jc/Jyu3.htm -->
<HTML><HEAD><TITLE>第五章 输入、界面和网络</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.2614.3500" name=GENERATOR><LINK
href="java04.css" rel=stylesheet type=text/css>
<SCRIPT language=JavaScript>
<!-- Hide the script from old browsers --
// Michael P. Scholtis (mpscho@planetx.bloomu.edu)
// All rights reserved. January 15, 1996
// You may use this JavaScript example as you see fit, as long as the
// information within this comment above is included in your script.
function MakeArray(n){
this.length=n;
for(var i=1; i<=n; i++) this[i]=i-1;
return this
}
hex=new MakeArray(16);
hex[11]="A"; hex[12]="B"; hex[13]="C"; hex[14]="D"; hex[15]="E"; hex[16]="F";
function ToHex(x){ // Changes a int to hex (in the range 0 to 255)
var high=x/16;
var s=high+""; //1
s=s.substring(0,2); //2 the combination of these are the same as the trunc function
high=parseInt(s,10); //3
var left=hex[high+1]; // left part of the hex-value
var low=x-high*16; // calculate the rest of the values
s=low+""; //1
s=s.substring(0,2); //2 the combination of these are the same as the trunc function
low=parseInt(s,10); //3
var right=hex[low+1]; // right part of the hex-value
var string=left+""+right; // add the high and low together
return string;
}
function rainbow(text){
text=text.substring(3,text.length-4); // gets rid of the HTML-comment-tags
color_d1=255; // any value in 'begin' 0 to 255
mul=color_d1/text.length;
for(i=0;i<text.length;i++){
color_d1=255*Math.sin(i/(text.length/3)); // some other things you can try>> "=255-mul*i" to fade out, "=mul*i" to fade in, or try "255癕ath.sin(i/(text.length/3))"
color_h1=ToHex(color_d1);
color_d2=mul*i;
color_h2=ToHex(color_d2);
document.write("<FONT COLOR='#FF"+color_h1+color_h2+"'>"+text.substring(i,i+1)+'</FONT>');
}
}
// --End Hiding Here -->
</SCRIPT>
<SCRIPT LANUGAGE="JavaScript">
<!--
function pop(pageurl) {
var
popwin=window.open(pageurl,"popWin","scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,resizable=no,width=700,height=450");
return false;
}
//-->
</SCRIPT>
<STYLE type=text/css>.main {
FONT-FAMILY: "宋体"; FONT-SIZE: 9pt
}
</STYLE>
<SCRIPT language=LiveScript>
function WinOpen() {
msg=open("","DisplayWindow","toolbar=no,directories=no,menubar=no");
msg.document.write("");
msg.document.write("<CENTER><H1>酷毙了</H1><h2>这 是<B>JavaScript</B>所开的视窗!</h2></CENTER>");
}
</SCRIPT>
</HEAD>
<BODY background=bk.jpeg bgColor=#ffffff leftMargin=0 text=#000000
topMargin=0 marginwidth="0" marginheight="0" tracingsrc="file:///D|/tiu.jpg"
tracingopacity="35">
<p> </p>
<H3>第五章 输入、界面和网络</H3>
<p> 在上一章中,介绍了如何在Java的Applet中绘制图形、动画和加入声音。这一章要介绍如何设计人机交互界面、如何接收用户的输入以及如何处理这些输入。</P>
<p> <a name="51"></a>5.1 接收鼠标、键盘的输入</P>
<p> Java中的事件(Event)处理是AWT(Abstract WindowingToolkit)的一部分。当某些情?况发生时,例如鼠标的移动、键盘的按键等,会触发相应的事件。而通过这些事件,AWT构件与用户或AWT构件之间就可以进行某种通讯。AWT对事件的处理分为两种情况,一种是由AWT或浏览器负责处理,例如paint()方法,还有一种是不作处理,例如鼠标的移动。在这一节里,我们要讨论的是对于这些AWT不作处理的方法,如何自己编写并覆盖这些事件处理方法,例如接收鼠标、键盘的输入。关于AWT如何处理这些事件,在本节的最后一部分将专门讨论。为了接收鼠标、键盘的输入,可把它们相应的事件分成三类:鼠标的按键;鼠标的移动或拖动;键盘的输入。</P>
<p> <a name="511"></a>5.1.1 鼠标的按键</P>
<p> 对于鼠标的按键,AWT会产生两种事件。当鼠标左键按下时产生mouseDown事件,当鼠标左键弹起时产生mouseUp事件。对于这两种事件,系统会分别调用相应的处理方法mouseDown()和mouseUp()。所以为了在程序中接收这两种事件,需要在程序中覆盖这两个事件的处理方法。例如对mouseDown()方法,其调用方式为:<br>
public boolean mouseDown(Event evt, int x, int y) {<br>
………<br>
}<br>
其中X,Y是事件发生时鼠标的位置,evt参数是由系统产生的Event类的一个实例,它包含了关于这个事件的一些信息。如果将程序改写为:<br>
public boolean mouseDown(Event evt, int x, int y) {<br>
System.out.println(*A mouse click happened*);<br>
return true;<br>
}<br>
那么在每次鼠标按下时,都会输出这句话。mouseUp()的使用与mouseDown()是相同的。有一点需要说明的是,这个方法必须返回一个布尔值。返回什么样的布尔值,取决于方法对事件的处理。如果返回true,则表明方法已完成对事件的处理;如果返回false,则表明需要其它AWT构件来处理。在大多数情况下,都是返回true。<br>
下面是使用mouseDown()方法的一个较完整的例子。<br>
1: import java.awt.Graphics;<br>
2: import java.awt.Color;<br>
3: import java.awt.Event;<br>
4:<br>
5: public class triangle extends java.applet.Applet {<br>
6: int xspots = new int[3];<br>
7: int yspots = new int[3];<br>
8: int currspots = 0;<br>
9:<br>
10: public void init() {<br>
11: setBackground(Color.white);<br>
12: }<br>
13: <br>
14: public boolean mouseDown(Event evt, int x, int y) {<br>
15: if (currspots < 3) {<br>
16: xspots[currspots] = x;<br>
17: yspots[currspots] = y;<br>
18: currspots ++;<br>
19: repaint();<br>
20: }<br>
21: return true;<br>
22: }<br>
23: <br>
24: public void paint(Graphics g) {<br>
25: int i;<br>
26: g.setColor (Color.green);<br>
27: for (i= 0;i < 3; i++) {<br>
28: g.fillOval(xspots[i] - 2,yspots[i] - 2,4,4);<br>
29: }<br>
30: if (currspots == 3) {<br>
31: g.setColor(Color.red);<br>
32: for (i = 1; i<3; i++) {<br>
33: g.drawLine(xspots[i-1],yspots[i-1],xspots[i],yspots[i]);<br>
34: }<br>
35: g.drawLine(xspots[i-1], yspots[i-1], xspots[0], yspots[0]);<br>
36: }<br>
37: }<br>
38: }<br>
这个程序的功能是用鼠标在屏幕上选定三个点,然后将这三个点连成一个三角形。现在我们来解释一下这个程序。这个程序中使用了三个AWT类:Graphics,Color和Event类,这在程序的1-3行已标出。也可只用一句<br>
import java.awt.*;<br>
6-8行中,程序中使用了两个数组xspots和yspots来储存三个点的坐标值(在paint()方法中需要使用),另外设置一个变量currspots来记录已画点的个数。<br>
14-22行是mouseDown方法。每次鼠标按下后,都调用方法mouseDown()。它首先判断是否已画满三个点。如果未满,则在数组中加入该点的坐标值,并调用repaint()方法;如果已满,则不做处理。<br>
24-37行是paint方法。在上章中讲到,repaint()方法的功能是刷新背景,并调用paint()方法。因此在paint()方法中,首先将已有的点重新标出(原有点已被刷新),然后判断如果已有三个点,那么将三个点连成一个三角形。</P>
<p> <a name="512"></a>5.1.2 鼠标的移动</P>
<p> 鼠标的移动有两种情况,鼠标的移动和鼠标的拖动,同样也对应了两个方法mouseDrag和mouseMove。其调用方式和使用方法与mouseDown等相同:<br>
public boolean mouseDrag( Event evt, int x, int y) {<br>
………<br>
}<br>
下面是一个使用mouseDrag方法的例子。<br>
1: import java.awt.*;<br>
2:<br>
3: public class drawcircle extends java.applet.Applet {<br>
4: Point start,end;<br>
5:<br>
6: public void init() {<br>
7: setBackground(Color.white);<br>
8: }<br>
9:<br>
10: public boolean mouseDown(Event evt, int x, int y) {<br>
11: start = new Point(x,y);<br>
12: return true;<br>
13: }<br>
14:<br>
15: public boolean mouseDrag(Event evt, int x, int y) {<br>
16: end = new Point(x,y);<br>
17: repaint();<br>
18: return true;<br>
19: }<br>
20:<br>
21: public void paint(Graphics g) {<br>
22: g.setColor(Color.blue);<br>
23: if (start.x <= end.x)<br>
24: if (start.y <= end.y)<br>
25: g.drawOval(start.x, start.y, end.x-start.x, end.y-start.y);<br>
26: else g.drawOval(start.x, end.y, end.x-start.x, start.y-end.y);<br>
27: else<br>
28: if (start.y <= end.y)<br>
29: g.drawOval(end.x, start.y, start.x-end.x, end.y-start.y);<br>
30: else g.drawOval(end.x, end.y, start.x-end.x, start.y-end.y);<br>
31: }<br>
32: }<br>
这个程序是用来模拟Windows中Paintbrush的画圆处理。它的处理方法是鼠标按下的位置是起始点,然后拖动鼠标,松开鼠标时的位置为结束点,在这两点形成的长方形中画一个内切椭圆。这个程序中第4行,使用了两个Point类型的变量start和end来存放起始点和结束点的坐标。<br>
10-13行是mouseDown方法,它的功能是在每次鼠标按下时给起始点赋值,15-19行是mouseDrag方法。因为在鼠标拖动时,结束点的位置尚未确定,所以,在每次调用mouseDrag时,都要设置新的结束点坐标,并调用repaint方法。一但鼠标松开,就以最后一次调用mouseDrag时确定的坐标为结束点坐标。<br>
21-31行是paint方法,这里考虑到起始点与结束点的位置关系,所以用了双重判断,并调用画圆方法。这个程序执行的结果是只能在屏幕上画出一个圆,这是因为程序中只有一对变量来储存起始点和结束点的坐标。每次画新圆时,已画的圆就被刷新。如果象上小节的例子中,设置两个数组,则可以把画出的圆保留下来。但这个方法也有缺点,能显示的圆的数量受数组大小的限制。最好的解决办法是用上章中提到的双重缓冲的思想,使用一个缓冲区来保存屏幕上的图像。除了mouseDrag和mouseMove以外,Java中还提供两个相似的方法mouseEnter和mouseExit。这两个方法是在鼠标进入和离开一个Applet画面时被调用。它们的调用方式与前面的几个相同。<br>
public boolean mouseEnter (Event evt, int x, int y) {<br>
………<br>
}</P>
<p> <a name="513"></a>5.1.3 键盘的输入</P>
<p> 当用户按下或松开键盘的按键时,会产生键盘事件。相应的处理方法是keyDown和keyUp。它们的调用方式与上面的略有不同。<br>
public boolean keyDown (Event evt, int key) {<br>
···<br>
}<br>
这里的key参数是一个整数变量,是所按下的键的ASCII值。可以用类型转换(char)key将其转成字符类型。keyUp的调用方式相同。这两种方法的区别是使用场合不同。如果将按住键不放解释为一连串相同的输入时,用keyDown来处理;而将按住键不放解释为一个字符输入时,用keyUp来处理。下一个问题是对于某些特殊键,如Home、End、PageUp、PageDown和方向键等,如何处理。最容易想到的是根据ASCII值来判断,但有谁记得住它们的ASCII值呢?Java中提供了较为简单的方法,它将这些特殊ASCII值定义成Event类的变量。例如判断是否Home键,可以写成:<br>
if (key = = Event.HOME) {<br>
………<br>
}<br>
这样在编写程序时,就方便多了。表一是这些特殊键所对应的常量。后面三个键是组合键,Shift,Ctrl,Alt键,这些键与其它键一起使用往往有特殊的含义。在Java的Event类还另外提供三个方法shiftDown(),metaDown(),controlDown()来判断Shift、Alt、Ctrl键是否按下。使用方法如下:<br>
public boolean keyDown (Event evt, int key) {<br>
if (evt.shiftDown())<br>
……… //显示大写字母<br>
else<br>
……… //显示小写字母<br>
}</P>
<p> <a name="514"></a>5.1.4 事件处理器(Event Handler)</P>
<p> 在Java的AWT中有一个事件处理器(Event Handler),事件处理器负责接收发生的事件,并对事件作出处理。上面介绍的这些常用的事件处理方法实际上都是由事件处理器来调用的。事件处理器的调用方式是<br>
public boolean handleEvent(Event evt) {<br>
···<br>
}<br>
在事件处理器中根据Event类参数evt的id值来判断发生事件的种类,针对用户界面(UI)构件的事件(下一节将会介绍)、键盘的按键、鼠标的操作、窗口的创建、移动、撤销等等。如果手头有Java
API reference的话,可以自己查阅一下。在某中情况下如果需要覆盖handleEvent方法,应相当慎重。因为对于原来的这些事件处理方法,除非在覆盖后的方法中加以指出,否则是不会被调用的。比较可靠的覆盖方法是:<br>
public boolean handleEvent (Event evt) {<br>
if (evt.id == Event.KEY_PRESS ) {<br>
……… //处理键盘操作<br>
return true;<br>
}<br>
else {<br>
return super.handleEvent(evt);<br>
}<br>
}<br>
这里是将余下的事件处理交给handleEvent的父类处理,从而保证对事件的正常处理。 </P>
<p> </P>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -