📄 ch4.htm
字号:
<BLOCKQUOTE><TT>Font f = new Font("Helvetica",Font.BOLD + Font.ITALIC,36);</TT></BLOCKQUOTE><P>Fonts can be tied to a component through the <TT>setFont()</TT>method. To create the previous font and tie it to a label, thefollowing code could be invoked:<BLOCKQUOTE><TT>Label l = new Label("My Label");<BR>l.setFont(new Font("Helvetica", Font.BOLD + Font.ITALIC,36));</TT></BLOCKQUOTE><P>A reference to a component's Font can be retrieved through <TT>getFont()</TT>.<P>Another way to use fonts is in the <TT>paint()</TT>method. The Graphics class used in <TT>paint()</TT>can have the current font set through the <TT>setFont()</TT>method. For example, Listing 4.4 provides the code for an appletthat paints a series of Strings containing a row number. Figure4.3 shows the output. When the <TT>paint()</TT>method begins, a new font is created and set to the graphics object;this font is now the current font used for the following graphicscalls. The <TT>drawString()</TT> methodis then called repeatedly with the y coordinate being dynamicallycalculated.<P><A HREF="f4-3.gif" ><B>Figure 4.3 </B>: <I>A Font applet using hardcoded coordinates</I></A><HR><BLOCKQUOTE><B>Listing 4.4. Code for Font applet using hard-coded coordinates.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.awt.*;<BR>import java.lang.*;<BR>import java.applet.*;<BR><BR>// This aspect throws a string into the applet<BR>// display separated by a height difference of the<BR>// current font<BR>public class FontTest extends Applet {<BR> public void paint(Graphics g) {<BR> int y;<BR> Font f = new Font("Helvetica",Font.BOLD+ Font.PLAIN,16);<BR> g.setFont(f);<BR> for (int i = 0; i < 5;++i) {<BR> y = 40 +(i * 20);<BR> g.drawString("Row" + i + " of text output.",10,y);<BR> } // end for<BR> }<BR>}</TT></BLOCKQUOTE><P>There are a couple of things about this applet that are not quiteoptimal. First of all, it isn't good to create a new Font in thepaint routine. Painting occurs frequently and font creation isan expensive operation. It is faster and more efficient to createthe font only once, as in the <TT>init()</TT>method.<P>The other thing that might be avoided is using hard-coded values,which is notorious for displays that do not appear uniformly acrossdifferent platforms. (After all, that is why AWT has layouts!)Although this applet might look decent across platforms, it givesan excuse for showing a better way of using coordinates. Thisis where the FontMetrics class comes in.<P>FontMetrics is used to get a variety of information about a Fontobject. Such information includes the font's dimensions, how biga String or character using that font would be, and so forth.Table 4.1 lists some of the methods of the FontMetrics class.<BR><P><CENTER><B>Table 4.1. FontMetrics methods.</B></CENTER><P><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR VALIGN=TOP><TD WIDTH=129><I>Method</I></TD><TD WIDTH=461><I>Description</I></TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>charWidth</TT></TD><TD WIDTH=461>Returns width of character using this font.</TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>GetAscent</TT></TD><TD WIDTH=461>Returns the ascent of the font (distance between the baseline and top of the character).</TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>GetDescent</TT></TD><TD WIDTH=461>Returns descent of font (distance from the baseline of the font and its bottom).</TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>getHeight</TT></TD><TD WIDTH=461>Returns total height of font (ascent + descent + leading).</TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>getLeading</TT></TD><TD WIDTH=461>Returns the line spacing of the font.</TD></TR><TR VALIGN=TOP><TD WIDTH=129><TT>stringWidth</TT></TD><TD WIDTH=461>Returns the number of pixels a String using this font will take.</TD></TR></TABLE></CENTER><P><P>You can retrieve a FontMetrics object for a specific font in acouple of ways. First of all, the FontMetrics object can be createdfrom scratch by using its constructor; it takes the Font in questionas its only parameter. The reference to the FontMetrics can alsobe taken directly from the Graphics class by using the <TT>getFontMetrics()</TT>method. The first technique is used when the program is not painting,but that is when the latter technique is applied. Finally, itcould retrieve from the default toolkit with a method also named<TT>getFontMetrics()</TT>.The nextsection explains how the Toolkit class works.<P>Figure 4.4 shows an improved version of the Font applet throughthe use of FontMetrics; Listing 4.5 gives the new code. In thisversion of the applet, each of the String displays are equallyincremented by the height of the font. The code calculates theheight increment from the <TT>getHeight()</TT>method of the FontMetrics reference of the Graphics object. Thenew code is also more efficient than the previous example sinceit creates the font only once, at initialization.<P><A HREF="f4-4.gif" ><B>Figure 4.4 </B>: <I>A Font applet using FontMetrics.</I></A><HR><BLOCKQUOTE><B>Listing 4.5. Code for a Font applet that uses FontMetrics.<BR></B></BLOCKQUOTE><BLOCKQUOTE><TT>import java.awt.*;<BR>import java.lang.*;<BR>import java.applet.*;<BR><BR>// This aspect throws a string into the applet<BR>// display separated by a height difference of the<BR>// current font<BR>public class FontTest extends Applet {<BR> Font f;<BR> // Create the font...<BR> public void init() {<BR> f = new Font("Helvetica",Font.BOLD+ Font.PLAIN,16);<BR> }<BR> // Paint using TextMetrics to set the heightin even<BR> // increments...<BR> public void paint(Graphics g) {<BR> // Set the font<BR> g.setFont(f);<BR> // Always increment by twicethe height of the font...<BR> int heightIncrement = 2* g.getFontMetrics().getHeight();<BR> int y = 0;<BR> for (int i = 0; i < 5;++i) {<BR> y += heightIncrement;<BR> g.drawString("Row" + i + " of text output.",10,y);<BR> } // end for<BR> }<BR>}</TT></BLOCKQUOTE><HR><P>The tutorial that follows will have even more examples of fonts,including a dialog box that can be used to select a font family,size, and style.<H3><A NAME="TheToolkitClass">The Toolkit Class</A></H3><P>The AWT Toolkit class provides the link between the AWT system-independentinterface and the underlying platform-based toolkit (such as Windows).The class is abstract, so the <TT>getDefaultToolkit()</TT>method must be called to get a reference to the actual Toolkitobject. Once this is done, all kinds of information about theunderlying environment can be revealed. By working with the Toolkit,this underlying information can be used in a way that does notcompromise portability.<P>For example, the following code gets a list of all the fonts availableon the native platform and prints them out:<BLOCKQUOTE><TT>String fontList[] = Toolkit.getDefaultToolkit().getFontList();<BR> for (int i = 0; i < fontList.length;++i)<BR> System.out.println(fontList[i]);</TT></BLOCKQUOTE><P>If the fonts used in an applet are derived from this list, versususing hard-coded font names, the portability of an applet willbe improved. The <TT>getFontMetrics()</TT>method returns the screen metrics of a font.<P>Another useful Toolkit method is <TT>getScreenSize()</TT>.This returns the full-screen dimensions of the native platform.If you want to create a window that fills up the screen, thesedimensions will be useful. The <TT>getScreenResolution()</TT>method returns the dots-per-inch resolution of the screen.<P>The Toolkit class also provides a variety of methods for usingimages, including a method for synchronizing the screen's graphicsstate. This <TT>sync()</TT> methodcan be used in animation to avoid flicker.<H2><A NAME="IOandStreams"><FONT SIZE=5 COLOR=#FF0000>I/O andStreams</FONT></A></H2><P><I>Streams</I> are a traditional way of representing a connectionbetween two objects. The types of streams that programmers aremost familiar with are ones between I/O devices (such as files)and processes or streams between two memory structures. Each endpointof a stream connection can have one or two channels: an inputchannel and an output channel. When a process is reading froma file, it reads from a stream that receives data from the filedevice's output channel. From the point of view of the process,it is managing an <I>input stream</I>. From the viewpoint of thefile device, it is sending an <I>output stream</I>. Figure 4.5illustrates the relationship.<P><A HREF="f4-5.gif" ><B>Figure 4.5 : </B><I>Stream relationships when a process reads from a file.</I></A><P>The JDK package for managing input and output interactions, calledjava.io, has the stream concept at its foundation. It is structuredon the notion of input and output streams just discussed. Thesestream classes permeate the Java programming environment. Theiruse ranges from file I/O to network programming to the widelyused <TT>System.out.println()</TT>method. There are few things that will increase the capabilitiesof a Java programmer more than a full understanding of Java streams.<H3><A NAME="StructureofthejavaioPackage">Structure of the java.ioPackage</A></H3><P>As just stated, the java.io package is based heavily on the notionof input and output streams. This is made clear by the diagramof significant java.io classes, shown in Figure 4.6. The mostimportant of these are, not surprisingly, the InputStream andOutputStream classes, which are generally used to read and writefrom a stream, respectively. They form the basis of an elaboratenetwork of stream classes that make it easy to build high-levelstreams, such as those that work on newline delimited ASCII data,to low-level streams, such as one that manages data on a byte-by-bytelevel. How this works will be explored in the upcoming discussionof the two foundation classes and their subclasses.<P><A HREF="f4-6.gif" ><B>Figure 4.6 :</B><I> Significant classes of the java to hierarchy.</I></A><P>Before engaging in a discussion of the input and output streamclasses, it's useful to look at some of the other aspects of JavaI/O programming. The File class can be used to get informationabout a file or directory on the host file system. For example,the following code checks to see whether a file exists in thecurrent directory and lists what is in the grandparent directory.<BLOCKQUOTE><TT>myFile = new File("File.txt");<BR> System.out.println("Thefile " + myFile.getName()<BR> +" existence is " + myFile.exists());<BR> File myDirectory = new File("..\\..");<BR> String s[] = myDirectory.list();<BR> System.out.println("Directorycontents: ");<BR> for (int i = 0; i < s.length;++i)<BR> System.out.println(s[i]);</TT></BLOCKQUOTE><P>As you might have observed in the constructor for the directoryobject, the naming conventions are based on the host file system.Consequently, hard coding such conventions can result in nonportablecode. Fortunately, the class provides some constants that canhide the platform-specific conventions. For example, the followingcode makes the directory constructor portable:<BLOCKQUOTE><TT>File myDirectory = new File(".."+ File.separator + "..");</TT></BLOCKQUOTE><P>The File class also offers a variety of other file operations.This includes the ability to delete or rename a file, create anew directory, and inspect a file's attributes. Note, however,that these operations are subject to the native environment'ssecurity constraints, discussed in the following section.<H2><A NAME="IOandSecurity"><FONT SIZE=5 COLOR=#FF0000>I/O andSecurity</FONT></A></H2><P>The Java language and its native environment (such as a browser)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -