450 Drawing3-D Rectangles
450 画3-D矩形
Almost all graphical user interfaces designed today have athree-dimensional look. Command buttons appear to rise off the page, and whenyou click on a button, the button appears to push in. You can create this 3-Dlook by using a simple highlight and shadow. Assuming that light comes from thetop-left, by applying highlight on the top and left side together with shadowon the right and bottom side, you can create a raised
look. Similarly, by placing a shadow on the top and left sidetogether with highlight on the right and bottom side, you can create apushed-in look. Figure 450 shows a raised and a pushed-in rectangle.
几乎所有现在设计的图形用户接口都有三维的式样. 命令按钮显得从页面上凸出来,而当你点击到某个按钮时,这个按钮看上去就被按下去了. 你可以利用简单的增亮色彩和添加阴影的方法来创建这种3-D的式样. 设想光线来自左上方,则在图形的左上方加亮,而同时要在其右下方添加阴影,这一图形就是凸的样子了. 类似地,如果在图形的左上方加阴影,而同时要在其右下方加亮色,这一图形就有凹下去的样子. 图450显示了一个凸出的和一个凹下去的长方形.
Production: Insert figurefig127.bmp [MCC]
Figure 450Raised and pushed-in rectangle using highlights and shadows.
图450 利用增亮和阴影产生凸起和凹下的矩形
The Java AWT provides the draw3DRect with which you can draw a3-D rectangle:
Java AWT提供了draw3DRect功能,利用它你可以来画一个3-D矩形:
draw3DRect(int x, inty, int width, int height, boolean raised);
The draw3DRect method is very similar to the drawRect method,but includes the extra raised parameter. You create a raised rectangle byspecifying true or a pushed-in rectangle by specifying false.
Draw3DRect方法与drawRect方法是很相象的,但多了一个额外的凸起参数. 你只要指明此参数为true就可画一个凸出的3-D矩形, 而指明此参数为false时就可画一个凹进的3-D矩形.
451 Drawinga Filled 3D Rectangle
451 画一填色的3-D矩形
In Tip 450, you learned that you can draw a 3-D rectangle usingthe draw3DRect method. Depending on your programs design, there may be timeswhen you will want a filled 3-D rectangle. To display a filled 3-D rectangle,your programs can use the fill3DRect method, the format of which is as follows:
在 TIP 450 中, 你已知道了你可以用draw3DRect来画一个3-D矩形.根据你的程序的情况,有时你会需要画一个3-D的填色矩形. 为了画一个填色3-D矩形, 你的程序可以使用fill3DRect方法. fill3DRect方法的格式如下:
fill3DRect(int x, inty, int width, int height,
boolean raised);
The fill3DRect method uses the same set of parameters as thedraw3DRect method. To create a raised rectangle, use the value true for theraised parameter. Likewise, to display a pushed-in rectangle, use the valuefalse.
Fill3DRect方法与draw3DRect使用相同的参数. 为了创建一个凸起的矩形,raised参数为true. 同样,为了创建一个凹进的矩形,raised参数应为false.
452Implementing Your Own 3-D Rectangle
452 实现你自己的3-D矩形
In Tip 450 and Tip 451, you learned how to draw 3-D rectanglesusing the draw3DRect and fill3DRect methods. If you use these methods withinyour program, you may find the 3-D effect very hard to see. The problem withthe built-in methods is that Java only draws the highlight and shadow borders onepixel wide. The following applet, three_d_rect.java, implements betterdraw3DRect and fill3DRect methods with borders that are three pixels wide, asshown in Figure 452:
在 TIP 450 和 TIP 451 中, 你已知道了怎样利用draw3DRect 和 fill3DRect 方法去画一个3-D矩形. 如果你在程序中使用了这些方法, 你可以发现3-D的效果不容易看清. 这种内建方法的问题在于, Java只用一个象素的线宽来画增亮的及阴影的边框线.以下的应用程序 three_d_rect.java利用draw3DRect 和 fill3DRect方法产生了有较好3-D效果的图形,如图452所示的,它带有三个象素宽度的边框:
import java.applet.*;
import java.awt.*;
public classthree_d_rect extends Applet {
public void draw3DRect(Graphics g, int x,int y,
int width, int height, boolean raised)
{
g.draw3DRect(x, y, width-1, height-1,raised);
g.draw3DRect(x+1, y+1, width-3,height-3, raised);
g.draw3DRect(x+2, y+2, width-, height-,raised);
}
public void fill3DRect(Graphics g, int x,int y,
int width, int height, boolean raised)
{
g.draw3DRect(x, y, width-1, height-1,raised);
g.draw3DRect(x+1, y+1, width-3, height-3, raised);
g.draw3DRect(x+2, y+2, width-, height-,raised);
g.fillRect(x+3, y+3, width-6, height-6);
}
public void paint(Graphics g)
{
g.setColor(Color.gray);
draw3DRect(g, 10, , 80, , true);
draw3DRect(g, 130, , 80, , false);
fill3DRect(g, 10, , 80, , true);
fill3DRect(g, 130, , 80, , false);
}
}
Figure 452 Drawing 3-D rectangles.
图452 画3-D;矩形
453 Usingthe darker and brighter Methods
453 使用darker和 brighter 方法
In Tip 452, you learned that you can create a 3-D effect usinghighlights and shadows. The Color class darker and brighter methods can helpyou obtain the highlight and shadow colors. You can also use these methods tocreate special effects like the one shown Figure 453, which was created by thebright_dark.java applet, as shown:
在 TIP 452 中, 你已知道了可以用加亮和阴影来创建3-D效果. Color类的darker和brighter方法能帮你得到其它的变亮和变暗色彩. 你同样可以利用这些方法来创建类似于图453所示的特殊效果, 它们是由应用程序bright_dark.java产生的:
import java.applet.*;
import java.awt.*;
public classbright_dark extends Applet {
Color dark_red = new Color(, 0, 0);
Color light_gray = new Color(2, 2, 2);
public void paint(Graphics g)
{
Color color;
// brighter colors
color = dark_red;
for (int i = 0; i < 16; i++)
{
g.setColor(color);
g.fillRect(0, i*, 300, );
color = color.brighter();
}
// darker colors
color = light_gray;
for(int i = 16; i < 32; i++)
{
g.setColor(color);
g.fillRect(0, i*, 300, );
color = color.darker();
}
}
}
Figure 453 Gradient color effectsusing the Color class bright and dark methods.
图453 利用Color类的brighter和darker方法产生渐变的色彩效应
454 FindingRegions That Need Updating Using the getClipRect Method
454 寻找需要利用getClipRect方法刷新的区域
When an area of a Java program needs to be redrawn, Java willautomatically call the update and paint methods. If only a portion of thedrawing area needs updating, Java will try to find the smallest rectangle thatencloses the required area and set it as the Graphics objects clipping region.Java then passes the Graphics object to the update and paint methods. Theupdate and paint methods ignore all drawings outside of the clipping rectangle,which allows faster screen updates.
当Java程序的一个区域需要重画时,Java就自动调用update 和 paint 方法. 如果作图区域中只有一部分需要刷新, Java将寻找出包含所需区域的最小矩形,并将其设成为一个Graphics对象的剪切区(clipping region). 然后Java把这Graphics对象传给update和paint方法. update和paint方法将不考虑剪切区之外的所有作图,这样使屏幕的刷新变快.
In most Java programs, programmers override the paint or updatemethod to draw the entire applet. To improve your programs performance, you candetermine the clipping region that needs updating and then only redraw thatportion of the window. To determine the clipping area, your programs can callthe getClipRect method. The following applet, get_cliprect.java, displays theclipping area that needs updating. Experiment with this applet by hiding andexposing part of the applet window with another application.
在Java程序中, 有的程序员不利用paint 或 update方法,而把整个应用程序区域重画一遍. 为了改进你的程序的性能, 你可以定出需要刷新的剪切区, 然后只重画位于剪切区窗口内的那一部分. 为了确定剪切区的范围, 你的程序可以调用getClipRect方法. 以下的程序get_ClipRect.java显示了需要刷新的剪切区. 本程序中利用隐蔽和暴露部分窗口的经验在编写其它应用程序时也是有用的.
import java.applet.*;
import java.awt.*;
public classget_cliprect extends Applet {
public void paint(Graphics g)
{
// draw a X on the screen
g.drawLine(0, 0, 300, 100);
g.drawLine(300, 0, 0, 100);
// print clipping rectangle to standardout
System.out.println("ClippingRect:" + g.getClipRect());
}
}
455Creating a Rectangle
455 创建一个矩形对象
As you learned in Tip 454, the getClipRect method returns aRectangle object that defines the current clipping region. Depending on yourapplets purpose, you may need to create your own Rectangle object. For example,you may want to define a clickable region within which the user can click themouse to select different objects. To create a Rectangle object, use one of thefollowing Rectangle constructors:
正如你在TIP 454 中所了解的那样, getClipRect方法返回一个矩形对象,它确定了当前的剪切区的大小. 按照你的应用程序的用途, 你有时会需要创建你自己的矩形对象.例如, 你可能需要定义一个可点击的(clickable)区, 用户利用mouse点击到区域中, 来选择不同的对象. 为了创建一个Rectangle对象,可使用以下各种Rectangle构造函数:
Rectangle();
Rectangle(int x, inty, int width, int height);
Rectangle(int width,int height);
Rectangle(Point p,Dimension d);
Rectangle(Point);
Rectangle(Dimension);
These constructors create the Rectangle object and initializethe x, y, width, and height fields which define the rectangles size andlocation.
这些构造函数创建了Rectangle对象, 并初始化x, y, width, 和height域, 来规定Rectangle对象的大小和位置.
456Understanding the Point and Dimension Class
456 了解Point类和Dimension类
Within an applet that performs graphics operations,there will be many times when you need to store x and y coordinates. In suchcases, your programs can use the Point class to create an object to store apoints coordinates. To create a Point object, use the following constructor:
在一执行图形操作的应用程序中, 你常常会需要存储x,y坐标. 这时,你的程序可以利用Point类来建立一个存放点的坐标的对象. 为了建立一个Point对象,可使用以下构造函数:
Point(int x, int y);
In a similar way, there will be times when your programs need tostore information about a graphic objects width and height. To store suchinformation, your programs can create a Dimension object using one of thefollowing constructor methods:
同样的理由, 你的应用程序有时可能需要保存图形对象的宽度和高度. 为了保存图形对象的这些信息, 你的程序可以利用以下构造函数之一来建立一个Dimension对象:
Dimension();
Dimension(Dimensiond);
Dimension(int width,int height);
The first constructor, with no argument, creates a Dimensionobject of zero width and zero height. The second constructor, with a Dimensionargument, creates a copy of the specified dimension. The third constructorcreates a Dimension object with the specified width and height.
不带自变量的第一个构造函数创建了一个零宽度零高度的Dimension对象. 带一个自变量的第二个构造函数创建了一个指定维数(dimension)的拷贝. 第三个构造函数创建了一个带由指定宽度和指定高度的Dimension对象.
457Checking If a Point Is Inside a Rectangle
457 检测一个点是否在一个矩形的内部
Within a graphics-based program, you may need to determine if apoint (x and y coordinates) reside within a rectangles coordinates. Todetermine if a point is within a rectangle, your programs can use the Rectangleclass inside method. The following applet, click_rect.java, implements twoclickable rectangular regions using a Rectangle object. When the user clickshis or her mouse within a region, the applet will display a message so stating:
在一基于图形的程序中,你可能需要确定一个点是否位于一个矩形内. 为了确定一个点是否位于一个矩形内,你的程序可以使用Rectangle类的inside方法. 以下的应用程序click_rect.java 利用Rectangle对象建立了两个可点击的矩形区域. 当用户在区域内点击他或她的mouse时,应用程序就会显示一个说明这一情况的信息:
import java.applet.*;
import java.awt.*;
public class click_rect extends Applet {
Rectangle a_rect = new Rectangle(10, 10, 80, );
Rectangle b_rect = new Rectangle(100, 10,80, );
public boolean mouseDown(Event e, int x, inty)
{
if (a_rect.inside(x,y)) // rectangle A clicked
System.out.println("Aclicked.");
if (b_rect.inside(x,y)) // rectangle B clicked
System.out.println("Bclicked.");
return true;
}
public void paint(Graphics g)
{
// draw the 2 clickable rectangles
g.setColor(Color.yellow);
g.fillRect(a_rect.x, a_rect.y,a_rect.width, a_rect.height);
g.fillRect(b_rect.x, b_rect.y,b_rect.width, b_rect.height);
g.setColor(Color.black);
g.drawString("A", a_rect.x +a_rect.width/2,
a_rect.y +a_rect.height/2);
g.drawString("B", b_rect.x +b_rect.width/2,
b_rect.y +b_rect.height/2);
}
}
Figure 457 shows a screen shot from the click_rect.java applet.As you can see, the applet defines two clickable rectangular regions: A and B.When the applet detects a mouse click, the applet will check if the clicklocation is inside one of these two rectangles. If the click location is insideA or B, the applet will display a message to the console window.
图457 显示了一个由应用程序click_rect.java产生的屏幕. 你可以看出,应用程序定义了两个可点击的矩形区:A 和 B. 当应用程序检查mouse点击,它将检查点击的位置是否在其中一个区域之内. 如果点击的位置是在区域A或B之内,应用程序将在用户的显示器窗口上显示一个信息.
Figure 457 An Applet with twoclickable rectangles.
图457 产生两个可点击矩形的应用程序
458Checking If Two Rectangles Intersect
458 检测两矩形是否相交
Within a graphics-based program, there may be times when youneed to test if two rectangle objects intersect. To determine if two Rectangleobjects intersect, your programs can use the Rectangle class intersects method.A game program, for example, might use the intersects method to detect if amissile has hit a spaceship. The following applet, intersects.java, illustratesthe use of the intersects method. Take time to experiment with the rectanglecoordinates, and test whether the rectangles intersect.
在一图形软件中,有时你会需要测试一下两个矩形是否相交. 为了测试两个矩形是否相交,你的应用程序可以使用Rectangle类intersects方法. 例如,一个game程序可能要用 intersects方法来检查一个火箭是否击中了宇宙飞船. 以下的应用程序intersects.java, 说明了intersects方法的用法. 化时间试验一下这些矩形坐标,看它们是否相交.
import java.applet.*;
import java.awt.*;
public classintersects extends Applet {
Rectangle g_rect = new Rectangle(10, 10, 80, );
Rectangle y_rect = new Rectangle(20, 20, 80,);
public void paint(Graphics g)
{
// draw the rectangles
g.setColor(Color.yellow);
g.drawRect(y_rect.x, y_rect.y,y_rect.width, y_rect.height);
g.setColor(Color.green);
g.drawRect(g_rect.x, g_rect.y,g_rect.width, g_rect.height);
g.setColor(Color.black);
if (y_rect.intersects(g_rect))
g.drawString("The two rectanglesintersect.", 10,90);
}
}
459 Usingthe intersection and union Methods
459 使用intersection方法(求交法) 和 union方法(求和法)
When your program uses Rectangle objects, you may need todetermine the screen region that holds both objects, or if two Rectangle objectsintersect. To find the intersection or the union of two rectangles, you can usethe Rectangle class intersection and union method. The intersection methodreturns the area where two Rectangle objects overlap. That is, the intersectionmethod returns the area that two Rectangle objects have in common.
当你的程序使用Rectangle 对象时, 你可能需要确定同时包含着两个对象的区域(区域的和),或者被两个对象同时包含的区域(区域的交). 为了确定区域的交与和,你可以使用Rectangle类的 intersection方法和 union方法. Intersection方法返回的是两个对象重叠的区域, 也就是两个对象的共同区域.
The union method, on the other hand, behaves differently thanyou might expect. The union method returns the smallest rectangle that enclosestwo Rectangle objects, instead of returning just the area covered by bothobjects. Figure 459 illustrates the behavior of the intersection and unionmethods.
另一方面, union方法产生区域可能和你期望的不同, 它返回的是包含着两个对象的一个最小矩型区域, 而不是正好这两个区域所复盖的区域. 图459说明了intersection方法与 union 方法的效果.
Figure 459 The intersection and unionof two rectangles.
图459 两个区域的交与"和"
460Creating a Polygon
460 创建一个多边形
To define complex shapes like triangles and pentagons,your programs can use a Polygon object. To create a Polygon object, use one ofthe following constructor methods:
要创建三角形,五边形这样的复杂形状,你的程序可一使用Polygon 对象. 为了创建一个Polygon对象,你可使用以下的构造函数:
Polygon();
Polygon(int xpoints[],int ypoints[], int npoints);
If you use the Polygon constructor without arguments, you willneed to use the addPoint method to define the polygons points. The followingapplet, poly_object.java, creates two polygons using each constructor. Figure460 illustrates how the Graphics class fillPolygon method displays polygons.
如果你使用了带由参数的 Polygon构造函数, 你将需要用addPoint方法来定义多边形的顶点. 以下的应用程序,poly_object.java,利用构造函数创建了两个多边形.图460说明了怎样利用 Graphics 类的 fillPolygon 方法来县示多边形.
Production: Insert code form poly_object.java [MCC] - cannot find! phil
Figure 460 An Applet with 3 polygons.
图460 生成3个多边形的应用程序
Rickhave anthony fax you the code forpoly_object.java.
461Checking if a Point is Inside a Polygon
461 检测一点是否在一多边形内
In Tip 460, you learned how to check if a specific point resideswithin a Rectangle object. In a similar way, there may be times when you needto know if a point resides within a Polygon object. For example, depending onthe shapes that appear within the applet window, you may want to create aclickable region that is defined by a polygon. The following applet,click_poly.java, creates three clickable triangles of different colors.
在TIP 460 中你已知道了怎样检测一点是否位于一个矩形的内部. 同样,有时你会需要检测一点是否位于一个多边形的内部. 例如, 根据应用程序窗口内的一个物体形状,你可能要建一个由多边形定义的可点击的区域. 以下应用程序click_poly.java, 创建了三个可点击的不同色彩的三角形.
import java.applet.*;
import java.awt.*;
public classclick_poly extends Applet {
int a_xpoints[] = { , 10, 70 };
int a_ypoints[] = { 20, , };
int a_len = a_xpoints.length;
int b_xpoints[] = { 120, 90, 1 };
int b_ypoints[] = { 20, , };
int b_len = b_xpoints.length;
Polygon a_poly = new Polygon(a_xpoints,a_ypoints, a_len);
Polygon b_poly = new Polygon(b_xpoints,b_ypoints, b_len);
public boolean mouseDown(Event e, int x, inty)
{
if (a_poly.inside(x,y)) // Polygon A clicked
System.out.println("Aclicked.");
if (b_poly.inside(x,y)) // Polygon B clicked
System.out.println("Bclicked.");
return true;
}
public void paint(Graphics g)
{
// draw the 2 clickable polygons
g.setColor(Color.yellow);
g.fillPolygon(a_poly);
g.setColor(Color.red);
g.fillPolygon(b_poly);
g.setColor(Color.black);
g.drawString("A", 30, );
g.drawString("B" , 110, );
}
}
462 Findingthe Bounding Box of a Polygon
462 寻找多边形的包围矩形
In some drawing programs, such as CorelDRAW, when you select anobject, the program creates a box to enclose the object which has handles thatlet you resize or move the object. In Java, a bounding box is the smallest boxthat contains a given polygon. The Polygon class getBoundingBox method returnsthe bounding box for a Polygon object. The following applet, boundbox.java,draws a Polygon object and then uses the getBoundingBox method to draw abounding box. In addition, the program uses the draw_handle method to addediting handles.
在某些图形软件中,如CorelDRAW, 当你选择一个对象时, 程序将创建一个包围这一对象的方框(box), 使你可以改变它的大小或移动位置. 在Java中,包围框是包含已给多边形的最小的框. Polygon类中的getBoundingBox 方法返回了多边形的最小包围框. 以下的程序,boundbox.java, 画出了一个多边形对象, 然后利用getBoundingBox 方法来画出一个包围框. 此外,程序还利用draw_handle 方法进行了编辑处理.
import java.applet.*;
import java.awt.*;
public class boundboxextends Applet {
int xpoints[] = {30, 90,1, 80, 90, 60};
int ypoints[] = {30, 10, , 70, , 30};
int num_pts = ypoints.length;
Polygon poly = new Polygon(xpoints, ypoints,num_pts);
void draw_handle(Graphics g, int x, int y)
{
g.fillRect(x-3, y-3, 7, 7);
}
public void paint(Graphics g)
{
// draw the polygons
g.setColor(Color.red);
g.fillPolygon(poly);
Rectangle bbox = poly.getBoundingBox();
g.setColor(Color.black);
g.drawRect(bbox.x, bbox.y, bbox.width,bbox.height);
draw_handle(g, bbox.x, bbox.y);
draw_handle(g, bbox.x + bbox.width,bbox.y);
draw_handle(g, bbox.x, bbox.y +bbox.height);
draw_handle(g, bbox.x + bbox.width,bbox.y + bbox.height);
}
}
Figure 462 shows the output of the boundbox.java applet.Although this program does not allow any actual editing, you can use theprogram as the basis of your own drawing program.
图462 显示了应用程序boundbox.java 的输出. 这个程序虽然不允许作任何实际的编辑, 但你可把此程序作为你的画图程序的一个基础.
Figure 462 An applet illustrating the getBoundingBoxmethod.
图462 说明getBoundingBox方法如何使用的一个应用程序
463Creating Fonts
463 创建字体
In previous tips, you have learned how to draw text to thescreen. In each case, the program drew the text using the default font. Withinyour programs, you can change the current font by creating new Font objects ofdifferent names, styles, and point sizes using the Font constructor, the formatof which is as follows:
在以上的TIP中,你已知道了怎样在屏幕上画字. 程序画字时每次都使用缺省字体. 在你的程序中, 你可以利用Font构造函数来创建不同名称,不同型式(style),不同大小的字体对象, 由次来改变当前的缺省字体.Font构造函数的格式如下:
Font(String name, intstyle, int size);
The name parameter specifies the font name, such as Courier orTimesRoman; Tip 464 will show you how to get a list of available fonts. Thesecond parameter specifies the font style, which can be Font.PLAIN, Font.BOLD,Font.ITALIC, or the combination of BOLD and ITALIC, such as Font.BOLD +Font.ITALIC. The third parameter specifies the fonts point size. For example,the following method call creates a 1 point bold
Courier font:
Font函数中指示的name参数可以是 Couriar, Times, Roman等字体名; TIP 464 将向你显示怎样获得一系列的可用字体. 第二个参数style指明了字体的型式,它可以是Font.PLAIN(普通字体),Font.BOLD(粗体), Font.ITALIC(斜体),或者可以是它们的组合, 如Font.BOLD + Font.ITALIC(粗斜体). 第二个参数size指明了字体的大小,用点数表示. 例如, 以下方法建立了一个1点couriar粗体:
Font myFont = new Font(Courier,Font.BOLD, 1);
464 FontsAvailable in Java
464 Java中可用的字体
Java defines five platform-independent font names which youshould find available on all platforms. You may use these names as the firstparameter to the Font constructor: Courier, Dialog, Helvetica, TimesRoman, andSymbol. When an applet creates a Font object, Java maps the font to aplatform-dependent font. For example, Java maps the Helvetica font to the Arialfont under Microsoft Windows. You may choose to specify a font name other thanthe five standard ones. However, if the font you specify is not available, Javawill automatically pick an available one for you.
Java定义了五种与平台无关的字体名, 你在任何平台都可以使用它们, 你可用它们作为构造函数font的第一个参数,它们是: Courier, Dialog, Helvetica, TimesRoman及 Symbol. 当你的应用程序创建一个 Font 对象时, Java 把字体map到平台无关的字体. 例如, Java在MicrosoftWindowsay中,将Helvetica体 map到Arial体. 你可以选择以上五种字体以外的字体, 但, 如果你所指定的字体不能使用,Java将自动为你选用另一种字体.
464 Drawingwith Different Fonts
464 用不同的字体来写字
In Tip 463, you learned how to create a Font object. To use aFont object to display text, you must use the Graphics class setFont method toselect the font. The following applet, fonts.java, draws several lines of textusing different font names, styles, and point sizes, as shown in Figure 464.
在TIP 463中,你已知道了怎样创建一字体对象. 为了用一种字体来显示文本, 你必须用Graphics类的setFont 方法来选择字体. 以下的fonts.java程序利用不同的字体名,字体类型,以及字体大小来写了几行字,如图464所示那样:
import java.applet.*;
import java.awt.*;
public class fontsextends Applet {
Font f1 = new Font("Helvetica",Font.PLAIN, 18);
Font f2 = new Font("Helvetica",Font.BOLD, 10);
Font f3 = new Font("Helvetica",Font.ITALIC, 12);
Font f = new Font("Courier", Font.PLAIN, 12);
Font f = new Font("TimesRoman",Font.BOLD + Font.ITALIC, 1);
Font f6 = new Font("Dialog",Font.ITALIC, 1);
public void paint(Graphics g)
{
g.setFont(f1);
g.drawString("18pt plainHelvetica", , 20);
g.setFont(f2);
g.drawString("10pt boldHelvetica", , );
g.setFont(f3);
g.drawString("12pt italicHelvetica", , );
g.setFont(f);
g.drawString("12pt plainCourier", , 7);
g.setFont(f);
g.drawString("1pt bold & italicTimes Roman", , 92);
g.setFont(f6);
g.drawString("1pt italicDialog", , 111);
}
}
Figure 465 An Applet illustrating theuse of various font names, style, and point sizes.
图465 一个用来说命各种字体名,字体类型及字体大小用法的应用程序
466 Gettinga List of Available Fonts
466 获得一张可用字体表
As you have learned, to display text using a specific font, yourapplets must create a Font object, and then use the setFont method to selectthe font. Before your applet selects a font, you may want to determine if thefont is available. To get a list of available fonts, your programs can use theToolkit class getFontList method. The following applet, font_list.java,illustrates the use of the getFontList method:
正如你所了解的那样,为了用一种特殊的字体来显示文本,你的应用程序必须先创建字体对象,然后用setFont方法来选择字体. 在你的应用程序选择一种字体之前, 你可能想要确定它是否可用的. 为了获得一张可用字体表, 你的程序可以使用Toolkit类的getFontList方法. 以下的font_list.java程序说明了如何使用getFontList方法:
import java.applet.*;
import java.awt.*;
public class font_listextends Applet {
public void paint(Graphics g)
{
String fontlist[] =getToolkit().getFontList();
for(int i = 0; i < fontlist.length;i++)
{
Font f = new Font(fontlist[i],Font.BOLD, 1);
g.setFont(f);
g.drawString(fontlist[i], , i * 20 +20);
}
}
}
467 FindingInformation on a Font
467 寻找一个字体的信息
When your programs display text, there will be times when youneed to get information about the current font. For example, before you displaytext, you may need to test the current font size to make sure the text will fitwithin the window region you desire. To learn specifics about the current font,your programs must first use the Component class getFont method to get thecurrent Font object. Next, to get information about the current font, yourprogram can use the Font class methods listed in Table 467.
当你的程序显示文字时,你有时会需要获得当前字体的信息. 例如,在你显示文字前,你可能需要测试一下当前字体的大小, 以保证所写的文字能写在你所需的窗口区域内. 为了了解当前字体的细节, 你的程序必须先用Component 类的 getFont方法以取到当前的Font对象. 然后,为了获得当前字体的信息, 你的程序可以使用列于表467中的Font类方法.
Method Purpose
-----------------------------------------------------------
getName Returns the name of the font
返回字体名
getSize Returns the point size of the font
返回字体名
getStyle Returns the style of the font
返回字体类型
isBold Returns true if it is a bold font
返回true, 如果字体为粗体
isItalic Returns true if it is a italic font
返回true, 如果字体为斜体
isPlain Returns true if it is a plain font
返回true, 如果字体为普通体
-----------------------------------------------------------
Table 467 Font classmethods that return information about a font.
表467 返回字体信息的Font类方法
The following init method displays the name, style, and size ofthe current font:
以下的init方法显示当前字体的名称,类型以及大小
public void init()
{
Font f = getFont();
System.out.println(Name: + f.getName());
System.out.println(Style: + f.getStyle());
System.out.println(isBold: + f.isBold());
System.out.println(isItalic: + f.isItalic());
System.out.println(isPlain: + f.isPlain());
System.out.println(Size: + f.getSize());
}
468Understanding Font Metrics
468 了解字体点阵
In Tip 467, you learned how to use Font class methods to obtainthe current fonts point size. Before you learn how to gather more informationabout the current font metrics, such as the baseline and character width, youneed to better understand several key terms. Later, to correctly place text onthe screen, or to align text with other objects, you will need to takeadvantage of several font characteristics. Figure 468 will help you understandseveral key font metrics.
在TIP 467中, 你已知道了怎样使用Font类方法来获得当前字体的大小. 在你了解怎样收集更多的当前字体信息,诸如字符的基线(baseline),字符的宽度,等, 你必须首先更好地了解一些关键性的术语. 然后,为了把文字正确地写到屏幕上去,或者将文字与其它的对象的位置对准, 你还需要利用几个字体特性.图468将帮助你了解字体的几个主要特征.
Figure 468 Fontmetrics parameters.
图468 字体参数
469 How toGet Font Metrics Information
469 怎样得到字体点阵信息
In Tip 468, you learned about several key font characteristics.Using a FontMetrics object, your applets can get several of these metrics forthe current font. To create a FontMetrics object, you can use either thegetFontMetrics method or the FontMetrics(Font) constructor. Then, you can usethe FontMetrics class methods to find about specifics about the current font.Table 469 lists several of the FontMetrics methods.
在TIP 468中, 你已知道了几种重要的字体特性. 利用FontMetrics 对象,你的应用程序可以得到有关当前字体的这些信息. 为了创建FontMetrics 对象,可用getFontMetrics方法,或 FontMetrics(Font)构造函数. 然后,你可以用FontMetrics类方法来找到有关当前字体的说明. 表478 列出了几种FontMetrics方法.
Method Purpose
------------------------------------------------------------------------
getAscent() Returns the ascent of the font
返回字体的上升量
getDescent() Returns the descent of the font
返回字体的下降量
getLeading() Returns the leading of the font
返回字体的左边沿
getHeight() Returns the height of the font
返回字体的高度
charWidth(char ch) Returns the width of the characterspecified
bytesWidth(byte data[], int off, int len)
Returns the width ofthe byte array
返回字节数组的宽度
stringWidth(String str) Returns the width of the String
返回字符串的宽度
------------------------------------------------------------------------
Table 469 SeveralFontMetrics methods.
表469 几个FontMetrics 方法
For example, the following creates a FontMetrics object for thecurrent font, and then uses the charWidth method to return the pixel width ofthe 1-point Courier font letter C:
例如, 以下语句为当前字体创建了一个FontMetrics ,然后使用charWidth 方法来返回1点Courier体的字符C的象素宽度:
Font f = Font(Courier,Font.BOLD, 1);
FontMetrics fmetrics =new FontMetrics(f);
int len =fmetrics.charWidth(C);
470Underlining Your Text
470 在你的文本下加下划线
Although the Java AWT library lets you create new fonts that usethe bold and italic style, Java does not support underlined text. However,using the FontMetrics class stringWidth() method, you can find the width of astring and underline the text yourself. The following applet, underline.java,underlines a string, as shown in Figure 470:
虽然Java AWT库能让你选用新字体, 使用粗体字, 斜体字, 恰Java 不支持下划线的字符.但是, 利用FontMetrics 类的 stringWidth() 方法, 你可以找到字符串的宽度,然后由你自己来加下划线. 以下的应用程序,underline.java, 产生如图470所示的一根下划线.
import java.applet.*;
import java.awt.*;
public class underlineextends Applet {
Font f1 = new Font("TimesRoman",Font.PLAIN, 1);
String str = "This line is underlined";
public void paint(Graphics g)
{
int strlen =getFontMetrics(f1).stringWidth(str);
g.setFont(f1);
g.drawString(str, , 30);
// draw line to underline string
g.drawLine(, 30 + 1, + strlen, 30 + 1);
}
}
Figure 470 Underlinedtext string.
图 470添加字符串下划线
471 Drawinga Line of Text with Multiple Fonts
471 用几种字体来写出一行字
Although Java lets you select different fonts for drawing text,it is a more challenging task if you want to display text using different fontsor if you want to draw two strings of the same font on the same line. After youdisplay the first string, you must find its ending screen location, andposition the second string at that point. The following applet,two_string.java, uses the stringWidth method to find the width of a string, andthen uses the width information to draw a line of text using multiple fonts, asshown in Figure 471:
Java虽然让你选用不同的自字体来写字, 但如果你想在文本中使用几种不同的字体,或在同一行中用同一种字体写出两个字符串, 仍是困难的事情. 当你显示了第一个字符串之后, 你必须找到该字符串的结束点的屏幕位置, 并把第二个字符放在这一位置上.以下的应用程序two_string.java利用stringWidth方法来找出字符串的宽度,然后利用宽度信息来写出包含多种字体的一行字,如图471所示:
import java.applet.*;
import java.awt.*;
public classtwo_string extends Applet {
Fontf1 = new Font("Helvetica", Font.BOLD, 18);
Font f2 = new Font("Courier",Font.PLAIN, 12);
Font f3 = new Font("TimesRoman",Font.BOLD + Font.ITALIC, 12);
String s1 = "18pt-Bold Helvetica";
String s2 = "and ";
String s3 = "12pt-Bold-Italic TimesRoman ";
public void paint(Graphics g)
{
int x = ;
g.setColor(Color.blue);
g.setFont(f1);
g.drawString(s1, x, );
x += getFontMetrics(f1).stringWidth(s1);
g.setColor(Color.black);
g.setFont(f2);
g.drawString(s2, x, );
x += getFontMetrics(f2).stringWidth(s2);
g.setColor(Color.red);
g.setFont(f3);
g.drawString(s3, x, );
}
}
As you can see, the program increments the variable x, using thevariable to position each new string of text.
正如你所看到的, 程序将变量x的值不断增加,利用它来定新字符串的位置
Figure 471 Drawing a line of text with multiple fonts.
图471 写出一行包含多种字体的字
472Aligning Your Text
472 重排你的文本
Using the FontMetrics methods you examined in Tip 469, you canalign your text horizontally and vertically. In fact, as you will learn, havinga reusable class for drawing aligned text is quite handy. The following code,AlignedText.java, shows you how to build such a class. In this case, the codecreates the AlignedText class, which you can use within your other applets:
利用你在 TIP 469中考察的 FontMetrics 方法, 你可以把你的字符串按水平或垂直方向排列. 事实上,正如你将了解的那样, 为书写排好的文本字符而规定一个可重用的类是方便的. 以下这一AlignedText.java程序说明你怎样建立这一种类. 在此例子中所建立的类你可以用在你其它的应用程序中:
import java.awt.*;
public classAlignedText {
// Define constants for setting textalignment
public static final int LEFT = 0x00;
public static final int RIGHT = 0x01;
public static final int CENTER = 0x02;
public static final int BASELINE = 0x00;
public static final int TOP = 0x0;
public static final int BOTTOM = 0x08;
private int alignmentType;
public AlignedText()
{
alignmentType = LEFT | BASELINE; //default alignment
}
public void set_alignment(intalignment_type)
{
alignmentType = alignment_type;
}
public void drawString(Graphics g, StringaString , int x, int y)
{
FontMetrics fmetrics =g.getFontMetrics();
int len = fmetrics.stringWidth(aString);
if ((alignmentType & RIGHT) != 0)
x -= len; // offset x for right alignment
else if ((alignmentType & CENTER)!= 0)
x -= len/2; // offset x for center alignment
if ((alignmentType & TOP) != 0)
y += fmetrics.getAscent(); // offset y for top alignment
else if((alignmentType & BOTTOM) !=0)
y -= fmetrics.getDescent(); // offset y for bottom
//alignment
g.drawString(aString, x, y);
}
}
The AlignedText class lets you set the text alignment using theset_align method. You can set horizontal alignment with aligned_text.LEFT,aligned_text.RIGHT, or aligned_text.CENTER, as well as the vertical alignmentwith aligned_text.TOP, aligned_text.BOTTOM, and aligned_text.BASELINE. You canthen draw text using the AlignedText class drawString method. The followingapplet, aligntext_test.java, illustrates the use of the AlignedText class anddraws several text strings with different alignments, as shown in Figure 472:
AlignedText 类方法使你可利用set_align方法来设置文本的排列形式. 你可以利用aligned_text.LEFT,aligned_text.RIGHT, 或 aligned_text.CENTER 将text设成水平书写方式, 也可利用aligned_text.TOP,aligned_text.BOTTOM, 和 aligned_text.BASELINE将text设成垂直的书写方式. 然后你可利用AlignedText 类的 drawString方法来写text.
以下的应用程序 aligntext_test.java, 说明了AlignedText类的用法, 它还利用不同的排列方式写出了几个字符串,如图472所示:
import java.awt.*;
import java.applet.*;
public classaligntext_test extends Applet {
AlignedText aligned_txt = new AlignedText();
public void paint(Graphics g)
{
aligned_txt = new AlignedText();
g.setColor(Color.black);
g.drawLine(, 0, , 100);
g.setColor(Color.blue);
aligned_txt.set_alignment(aligned_txt.LEFT);
aligned_txt.drawString(g,"left", , 30);
aligned_txt.set_alignment(aligned_txt.CENTER);
aligned_txt.drawString(g,"center", , 60);
aligned_txt.set_alignment(aligned_txt.RIGHT);
aligned_txt.drawString(g,"right", , 90);
g.setColor(Color.black);
g.drawLine(100, , 300, );
g.setColor(Color.blue);
aligned_txt.set_alignment(aligned_txt.BOTTOM);
aligned_txt.drawString(g,"bottom", 100, );
aligned_txt.set_alignment(aligned_txt.BASELINE);
aligned_txt.drawString(g,"baseline", 160, );
aligned_txt.set_alignment(aligned_txt.TOP);
aligned_txt.drawString(g, "top",220, );
}
}
Figure 472 Text strings with different alignments.
图472 用不同形式排列的文本字符串
473 Gettinga GIF Image File from the Web
473 从Web得到一个GIF图象文件
The days of text-only Web pages are long gone. Todays Web pagesare loaded with GIF and JPEG images. You can also display GIF and JPEG imagefiles within your Java applets. Displaying an image file in Java involves twosteps: getting the image and drawing the image. To get a GIF or JPEG image filewithin a Java applet is a simple a matter of calling one of the followinggetImage methods:
只有文字的 Web页面时代早以过去了. 当今的Web页面是用GIF和JPEG图像装入的.在你的应用程序中你也可以装入和显示GIF和JPEG图像. 在Java中显示一个图像文件包括两个步骤: 获得图像和显示图像. 为了在Java应用程序中得到一个GIF图像文件或JPEG图像文件,只需简单地调用以下的getImage方法:
Image getImage(URLurl);
Image getImage(URLurl, String name);
Within the first getImage method, the url parameter must be aUniform Reference Locator (URL) that points to an image file on the Web. ThegetImage method returns an Image object that your program can later use toreference the GIF or JPEG image. For example, the following statement createsan Image object for the file sample.gif which resides on the server at,http://www.myserver.com:
在第一个getImage方法中, url参数必须是一个在Web上指向一个图像的 URL(Uniform Reference Locator,统一参考定位器). getImage方法返回一个你在此后可以用来引用的 GIF 或 JPEG 文件. 例如,以下的语句为驻留在服务器http://www.myserver.com上的sample.gif文件创建了一个图像对象.
Image img =getImage(new URL(http://www.abc.com/ sample.gif));
Notice the hardcoded pathname in this example. As a rule, it isnot good programming to hardcode the servers name within the source file.Should you later need to move the image file to a different server, you willneed to change the source code to match the servers location and recompile.Instead, your applet can use the getCodeBase method to locate an image file.With the second getImage method, the url parameter points to the location wherethe image file is and the name parameter specifies the name of the image file.For example, the following statement uses the getCodeBase method to get the serverand directory location that corresponds to the applet file and then uses thatlocation to locate the file sample.gif:
请注意例子中硬性规定的路径名(hardcoded pathname). 作为一个规则,把硬性规定的路径名放进一个源程序中不是一种好的程序设计方法. 假如你以后要把图像文件移到另一不同的服务器中,你将需要改变源程序来匹配服务器地址并重新编译一次. 与此相反, 你的程序可用 getCodeBase 方法来确定图象文件的地址. 利用第二种getImage方法,url参数将指向文件所在的地址,而名字参数指出文件的名字. 例如,以下的程序利用getCodeBase方法来获得对应与应用块文件的服务器和目录的地址,并用这一地址来定位文件 sample.gif:
Image img =getImage(getCodeBase(), sample.gif);
Be aware that neither of these getImage methods actually loads theimage. Instead, your applet loads the image when it first needs the applet.
注意,两种getImage方法实际上都没有装载文件. 你的应用程序装载文件是在第一次需要应用程序时进行的.
474 Drawingan Image
474 显示一个图象
As you learned in Tip 473, the getImage method returns an Imageobject for the specified GIF or JPEG image file. To display the Image object,your applets can use the drawImage method:
正如你在 TIP 473中所了解的那样, getImage方法为指定的GIF图像文件或JPEG图像文件返回一个Image对象. 为了显示这个Image对象, 你的应用程序可以利用darwImage方法:
booleandrawImage(Image img, int x, int y, ImageObserver observer);
The x and y parameters specify the location of theupper-left corner of the image. The following applet, draw_image.java, displaysa GIF image file named cow.gif, as shown in Figure 474:
其中x和y参数指定了图像的左上角位置. 以下的应用程序,draw_image.java, 显示一个名为cow.gif的GIF文件, 如图474所示:
import java.applet.*;
import java.awt.*;
public classdraw_image extends Applet {
Image img;
public void init()
{
img = getImage(getCodeBase(),"cow.gif");
}
public void paint(Graphics g)
{
g.drawImage(img, 0, 0, this);
}
}
Figure474 Applet that displays a GIF image file.
图 474 显示一个GIF 图像文件的应用程序
475Stretching an Image in Java
475 在Java中放大一个图象
In Tip 474, you learned how to displayan image within a Java applet. However, if the size of the display area isdifferent from the size of the image, you may want to stretch or shrink theimage to fit the area. As it turns out, there is another form of the drawImagemethod that lets you specify the image width and height:
在 TIP 474 中,你已知道了怎样在一个应用程序中显示一幅图象. 但是,你有时想要放大或缩小图像,以适合一个已定的区域. 在这种情况下, 可以使用另一种drawImage方法,它可让你指明图像的宽度和高度:
booleandrawImage(Image img, int x, int y, int width,
int height, ImageObserver observer);
When your programs use the drawImagemethod, the method draws to scale using the specified width and height. Thefollowing applet, stretch_image.java, shown in Figure 475, displays the sameGIF image as in Tip 474, but it is stretched to fill the entire applet area:
当你的应用程序利用drawImage方法时, 它将按指定的width, height参数大小来画图.以下的程序stretch_image.java产生图475所示的一个图象, 这是一个和图474相同的GIF图像,但它拉伸后填满了应用程序的整个窗口区域.
import java.applet.*;
import java.awt.*;
public classstretch_image extends Applet {
Image img;
public void init()
{
img = getImage(getCodeBase(),"cow.gif");
}
public void paint(Graphics g)
{
g.drawImage(img, 0, 0, 200, 100, this);
}
}
Figure 475 Applet thatdisplays a stretched image.
图 475显示一个伸拉的图像的应用程序
476Matching Java Background Color with HTML Page Background
476 使Java的背景颜色与HTML页面背景相匹配
As you have learned, you embedstatements that correspond to your Java applet within an HTML document. Attimes, you may want the background color of your applet to be the same as thebackground color of the HTML document. Unfortunately, Java does not automaticallymatch the background colors, nor does it provide a transparent background colorfor the applet. To match the following HTML documents background colors,perform the following steps:
正如你所了解的那样, 你嵌入了语句对应于一个 HTML 文档中的Java应用块. 有时,你可能想要使你的应用程序所用的背景颜色和HTML文档所用的颜色一致. 不幸的是,Java既不会自动地匹配颜色,也不能为应用程序提供一种透明的背景色. 为了匹配以下的 HTML 文档的背景颜色, 可执行以下几个步骤:
1.Pass a parameter to the applet thatspecifies the HTML documents RGB background color.
2.Create a matching RGB color in Javausing the Color constructor.
3.Assign the background color using thesetBackground method.
1. 将指示了 HTML 文档 背景的RGB颜色的参数传给应用程序;
2. 利用 Color 构造函数 在Java中创建一个 RGB颜色;
3. 利用setBackground 方法为背景颜色赋值.
The following HTML statements pass theRGB color FFCFCF as an HTML parameter named BGCOLOR:
以下的HTML语句 将RGB颜色FFCFCF 作为一个名叫BGCOLOR的HTML参数传递:
<HTML><BODYbgcolor="#FFCFCF" >
<APPLETCODE="match_back.class" WIDTH=300 HEIGHT=100>
<paramname=BGCOLOR value="FFCFCF"></APPLET>
</BODY></HTML>
The following Java statements use thegetParameter method to determine the HTML background color. Next, thestatements use the setBackgruond method to set the background color:
以下的Java语句利用getParameter 方法来确定HTML 的背景颜色. 然后,语句利用setBackgruond 方法来设置背景的颜色:
public void init()
{
String arg =getParameter("BGCOLOR");
int bgColorVal = Integer.valueOf(arg,16).intValue();
setBackground(new Color(bgColorVal));
}
477 Matching Java Background Pattern with HTML PagePattern
477 使Java的背景图案与HTML页面图案相匹配
In Tip 476, you learned how to match aJava applets background color with the Web pages background. However, some Webpages use tiled image files for the background. You can use the same techniqueas in Tip xxx to pass the name of the background image file to the applet.Instead of changing the background color using the setBackground method, yourapplet can draw the background by tiling the image. The following HTMLstatements and Java code show you how to tile the background:
在 TIP 476中, 你已知道了怎样使Java应用程序的背景颜色与Web页面背景匹配. 但是, 某些Web页面使用了地砖式图像文件作为背景. 你可用和TIP XXX 一样的方法把背景图像文件的名称传递给应用程序. 你的应用程序可以不用setBackground方法来改变背景的颜色,而用帖图像的方法来画背景. 以下的 HTML 语句和Jaca程序告诉你怎样来贴背景图像:
<HTML><BODYBACKGROUND="pattern.gif" >
<APPLETCODE="tile_back.class" WIDTH=300 HEIGHT=100>
<paramname=BACKGROUND value="pattern.gif">
<param name=BGWIDTHvalue="">
<param name=BGHEIGHTvalue="">
</BODY></HTML>
The following init method uses thegetParameter method to get the HTML parameter values. Then, the statements tilethe image as specified by the parameters.
以下的 init方法使用getParameter 方法来获得 HTML参数值. 然后, 语句按照参数的指定来贴图像.
Image img;
int bg_width,bg_height;
public void init()
{
String arg =getParameter("BACKGROUND");
System.out.println("BACKGROUND="+ arg);
img = getImage(getCodeBase(), arg);
arg = getParameter("BGWIDTH");
bg_width = Integer.valueOf(arg,16).intValue();
arg = getParameter("BGHEIGHT");
bg_height = Integer.valueOf(arg,16).intValue();
}
public voidpaint(Graphics g)
{
int x, y;
// draw background pattern
y = 0;
while(y < size().height)
{
x= 0;
while(x < size().width)
{
g.drawImage(img, x, y, this);
x += bg_width;
}
y += bg_height;
}
}
When you use this technique for matchingbackground patterns, you should use random and seamless patterns. Otherwise,the discontinuity of the pattern between the Web page and the applet will forma visible edge. In this example, the size of the pattern image is passed to theapplet in parameters. Alternatively, in later tips you will learn how toinquire about an images size, rather than having to specify a size.
当你用这一方法来配背景的颜色时, 你应使用随机的或无间隙的模式图案.否者,在web页面和应用程序之间的不连续性将形成一条看得见的边. 在这一例子中, 模式图像的大小利用参数传递给应用程序. 另外一种方法,在以后的TIP中你将会知道,怎样查询图像的大小,而不必指明一个大小.