Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 20 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
20
Dung lượng
370,18 KB
Nội dung
character at a time using the reader.read() method. If the end of the file (EOF) is reached, this method returns –1. So the while loop checks for this as its con- dition. Although each character read in is not –1, write that character to the writer buffer anyway. Invoking the writer.close() causes the buffer to be cleared, written to the file, and closed. Figure 11.6 shows one run of the FileCopy application. 418 J a v a P r o g r am m i n g f o r t h e A b s o l ut e B e gi n n e r FIGURE 11.6 The FileCopy application copied the file1.txt file and saved the copy as copy.txt. Don’t forget to call the close() method on the BufferedWriter. If you don’t you won’t get any actual output. There is also a method called flush() which flush- es the buffer and writes it out to the file, but calling close() actually flushes the buffer before closing anyway. Keeping Score The ScoreInfoPanel class keeps score basically by keeping track of three integers: scoreValue keeps track of the current score, hiValue keeps track of the high score, and nLinesValue keeps track of the number of lines cleared. The ScoreInfoPanel class also provides methods for modifying these values such as setScore(int), setHiScore(int), and setLines(int) for setting these values to the given int value. It also provides addToScore(int) and addToLines(int) TRAP JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 418 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. methods for adding the given int value to these values. Here is the source code for ScoreInfoPanel.java: /* * ScoreInfoPanel * A Panel that shows the scoring info for a BlockGame * and shows the next block. */ import java.awt.*; import java.io.*; import java.text.NumberFormat; public class ScoreInfoPanel extends Panel { protected Label scoreLabel = new Label("Score: "), linesLabel = new Label("Lines: "), score = new Label(), hiLabel = new Label(), lines = new Label(), nextLabel = new Label("Next Block", Label.CENTER); protected int scoreValue = 0, hiValue = 0, nLinesValue = 0; protected BlockGrid nextBlockDisplay = new BlockGrid(6, 6, 10); public static int BLOCK = 1, ROW1 = 100, ROW2 = 300, ROW3 = 600, ROW4 = 1000, ROW4BONUS = 10000; protected Label[] points = { new Label("Block = " + BLOCK + " points"), new Label("1 Row = " + ROW1 + " points"), new Label("2 Rows = " + ROW2 + " points"), new Label("3 Rows = " + ROW3 + " points"), new Label("4 Rows = " + ROW4 + " points"), new Label("BONUS = " + ROW4BONUS + " points") }; NumberFormat nf = NumberFormat.getInstance(); Block block = null; public ScoreInfoPanel() { super(); nf.setMinimumIntegerDigits(8); //pack in zeros nf.setGroupingUsed(false); //no separators e.g. commas hiLabel.setForeground(Color.blue); readHiScore(); nextBlockDisplay.setBackground(Color.black); nextLabel.setForeground(Color.blue); scoreLabel.setForeground(Color.blue); linesLabel.setForeground(Color.blue); setScore(0); score.setAlignment(Label.CENTER); score.setForeground(Color.green); score.setBackground(Color.black); score.setFont(new Font("Courier New", Font.BOLD, 12)); setLines(0); 419 C h a p t e r 11 C u s t o m E v e n t H a n d l i n g a n d F i l e I / O JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 419 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. lines.setAlignment(Label.CENTER); lines.setForeground(Color.red); lines.setBackground(Color.black); lines.setFont(new Font("Courier New", Font.BOLD, 12)); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gridbag); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.anchor = GridBagConstraints.CENTER; addComp(hiLabel, gridbag, gbc); addComp(nextBlockDisplay, gridbag, gbc); addComp(nextLabel, gridbag, gbc); gbc.anchor = GridBagConstraints.WEST; for (int p=0; p < points.length; p++) { addComp(points[p], gridbag, gbc); } addComp(scoreLabel, gridbag, gbc); gbc.anchor = GridBagConstraints.CENTER; addComp(score, gridbag, gbc); gbc.anchor = GridBagConstraints.WEST; addComp(linesLabel, gridbag, gbc); gbc.anchor = GridBagConstraints.CENTER; addComp(lines, gridbag, gbc); } protected void addComp(Component comp, GridBagLayout g, GridBagConstraints c) { g.setConstraints(comp, c); add(comp); } protected void readHiScore() { try { BufferedReader r = new BufferedReader(new FileReader("hi.dat")); setHiScore(Integer.parseInt(r.readLine())); r.close(); } catch (Exception e) { setHiScore(0); } } public void saveHiScore() { try { BufferedWriter w = new BufferedWriter(new FileWriter("hi.dat")); w.write(String.valueOf(hiValue)); w.close(); } catch (Exception e) {} } protected void setHiScore(int h) { hiValue = h; hiLabel.setText("High: " + nf.format(h)); } 420 J a v a P r o g r am m i n g f o r t h e A b s o l ut e B e gi n n e r JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 420 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. public void setScore(int s) { scoreValue = s; score.setText(nf.format(s)); if (s > hiValue) setHiScore(s); } public void addToScore(int addValue) { scoreValue += addValue; setScore(scoreValue); } public void setLines(int l) { nLinesValue = l; lines.setText(nf.format(l)); } public void addToLines(int addValue) { nLinesValue += addValue; setLines(nLinesValue); } public void showBlock(Block b) { if (block != null) nextBlockDisplay.removeBlock(); block = b; nextBlockDisplay.setBlock(block); nextBlockDisplay.setBlockPos(new Point(1, 1)); nextBlockDisplay.addBlock(); nextBlockDisplay.repaint(); } public Insets getInsets() { return new Insets(5, 5, 5, 5); } } The ScoreInfoPanel uses labels to display its information, defined as follows: • scoreLabel is the label for the current score • score is the label for the actual numerical score • linesLabel labels the number of lines • lines is the label that displays the number of lines • highLabel labels and displays the high score on one line • nextLabel labels the box that shows the next block nextBlockDisplay is a BlockGrid instance that displays the next block. The show- Block(Block) method can be called, and the given Block will be displayed in the 421 C h a p t e r 11 C u s t o m E v e n t H a n d l i n g a n d F i l e I / O JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 421 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. nextBlockDisplay. The ScoreInfoPanel also provides some static constants that represent score values: BLOCK The score value for landing a block. ROW1 The score value for clearing one line with a single block. ROW2 The score value for clearing two lines with a single block. ROW3 The score value for clearing three lines with a single block. ROW4 The score value for clearing four lines with a single block. BONUS The score value for clearing four lines with a single block multi- ple times. It reads and writes the high score using a file named hi.dat. These are the meth- ods that do this: protected void readHiScore() { try { BufferedReader r = new BufferedReader(new FileReader("hi.dat")); setHiScore(Integer.parseInt(r.readLine())); r.close(); } catch (Exception e) { setHiScore(0); } } public void saveHiScore() { try { BufferedWriter w = new BufferedWriter(new FileWriter("hi.dat")); w.write(String.valueOf(hiValue)); w.close(); } catch (Exception e) {} } It works similarly to the FileCopy application, except the BufferedReader reads a whole line, which you actually did way back in Chapter 2, when you used a BufferedReader to read command-line input. It parses the string read in to an integer value by calling Integer.parseInt(r.readLine()). The readHiScore() method is not public because there is no reason for any other class to tell this class to read in the high score because it does it automatically in the constructor and keeps it up to date. The saveHiScore() method, on the other hand, is public because you want to wait until the game is over before you save the score. You’ll rely on the application pro- gram to tell you when that is. The BufferedWriter writes a whole string that rep- resents the high score by calling w.write(String.valueOf(hiValue)). Everything else is pretty much straight-forward, such as laying out these components. However, the use of the NumberFormat class needs some explanation. NumberFor- mat is part of the java.text package. It helps you format numbers. I created a 422 J a v a P r o g r am m i n g f o r t h e A b s o l ut e B e gi n n e r JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 422 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. new instance of a NumberFormat by calling NumberFormat.getInstance(). Number- Format is an abstract class, so it can’t have a direct instance. getInstance() returns the default number format. There are other methods for getting other types of instances such as getCurrencyInstace() and getPercentInstance(). nf is the NumberFormat. Calling nf.setMinimumIntegerDigits(8) does exactly what you’d expect it to do based on the name of the method. It expresses integers using a minimum of eight digits. For example, 27 is expressed as 00000027. nf.setGroupingUsed(false) makes sure that no commas separate the pieces of the number (so 1000 doesn’t use a comma like 1,000). Running Block Game from the CD will not allow you to maintain a high score. You can’t write a file onto the CD, so the high score won’t get saved. The excep- tion handling will cause this flaw to just be ignored. To save your high scores, either write your own copy, which you should be doing for learning purposes anyway, or copy the games files to your hard drive and run it from there. Creating the Block Game Application The Block Game application puts the PlayArea and ScoreInfoPanel classes together, along with a Play/Reset button so you can start a new game. The mem- bers it declares are as follows: lastNLines Holds the number of lines (rows) that were cleared the last time lines where cleared. playarea The PlayArea instance. infoPanel The ScoreInfoPanel instance. resetButton The button used for playing and resetting the game. block The current block that will be introduced to the PlayArea. nextBlock The block that will be introduced to the PlayArea after block lands. I, L, O, R, S, T, and Z Constants that represent the seven block shapes. I used the letter that looks most like the shape of the block. The createBlock() method pumps out one of the seven blocks. It generates a ran- dom number and then uses a switch statement to generate the block based on that random number and then returns that block. The initialize() method sets score values to zero and creates a new block for nextBlock. The intro- duceNextBlock() method sets block to nextBlock, creates a new block for TRAP 423 C h a p t e r 11 C u s t o m E v e n t H a n d l i n g a n d F i l e I / O JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 423 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. nextBlock, shows nextBlock in infoPanel, and calls playarea.introduce- Block(block) to make the block start falling into the PlayArea. The resetButton has an ActionListener that calls the playGame() method. This method calls ini- tialize() , playarea.clear() (for clearing the PlayArea when the game is reset), playarea.requestFocus() (so the PlayArea will immediately accept keyboard commands), and introduceNextBlock() to get things rolling. It adds an anonymous inner class to listen for PlayAreaEvents to the playarea instance. It checks for block landings. It adds the point values specified by the ScoreInfoPanel constants based on how many rows are cleared. After it adds the score it checks whether the block landed out of area by invoking the isOutO- fArea() method of the PlayAreaEvent class. If it isn’t out of area, it introduces the next block into the PlayArea, if it is, the game is over and it calls infoPanel.saveHiScore() to write the high score back to the file. Here is the full source code listing for BlockGame.java: /* * Block Game * The actual Application Frame for the Block Game. */ import java.awt.*; import java.awt.event.*; public class BlockGame extends GUIFrame { protected int lastNLines; protected PlayArea playarea; protected ScoreInfoPanel infoPanel; protected Button resetButton; protected Block block, nextBlock; protected final static int I = 0, L = 1, O = 2, R = 3, S = 4, T = 5, Z = 6; public BlockGame() { super("Block Game"); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setBackground(SystemColor.control); playarea = new PlayArea(10, 20, 20); setLayout(gridbag); playarea.setBackground(Color.black); constraints.gridheight = GridBagConstraints.REMAINDER; gridbag.setConstraints(playarea, constraints); add(playarea); 424 J a v a P r o g r am m i n g f o r t h e A b s o l ut e B e gi n n e r JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 424 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. infoPanel = new ScoreInfoPanel(); constraints.anchor = GridBagConstraints.NORTH; constraints.gridheight = 1; constraints.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(infoPanel, constraints); add(infoPanel); resetButton = new Button("Play/Reset"); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { playGame(); } }); constraints.gridwidth = constraints.gridheight = 1; gridbag.setConstraints(resetButton, constraints); add(resetButton); playarea.addPlayAreaListener(new PlayAreaListener() { public void blockLanded(PlayAreaEvent pae) { infoPanel.addToScore(ScoreInfoPanel.BLOCK); infoPanel.addToLines(pae.getRows()); switch (pae.getRows()) { case 1: infoPanel.addToScore(ScoreInfoPanel.ROW1); break; case 2: infoPanel.addToScore(ScoreInfoPanel.ROW2); break; case 3: infoPanel.addToScore(ScoreInfoPanel.ROW3); break; case 4: infoPanel.addToScore(ScoreInfoPanel.ROW4); if (lastNLines == 4) infoPanel.addToScore(ScoreInfoPanel.ROW4BONUS); break; } lastNLines = pae.getRows() > 0 ? pae.getRows() : lastNLines; if (!pae.isOutOfArea()) introduceNextBlock(); else infoPanel.saveHiScore(); } }); initialize(); pack(); setVisible(true); } public static void main(String args[]) { new BlockGame(); } 425 C h a p t e r 11 C u s t o m E v e n t H a n d l i n g a n d F i l e I / O JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 425 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. protected void initialize() { lastNLines = 0; infoPanel.setScore(0); infoPanel.setLines(0); block = createBlock(); nextBlock = createBlock(); } public void playGame() { initialize(); playarea.clear(); playarea.requestFocus(); introduceNextBlock(); } public void introduceNextBlock() { block = nextBlock; nextBlock = createBlock(); infoPanel.showBlock(nextBlock); playarea.introduceBlock(block); } //randomly returns one of the seven blocks protected Block createBlock() { Point[] squareCoords = new Point[4]; int randB = (int) Math.floor(Math.random() * 7); int s; Color c; switch (randB) { case I: squareCoords[0] = new Point(2, 0); squareCoords[1] = new Point(2, 1); squareCoords[2] = new Point(2, 2); squareCoords[3] = new Point(2, 3); s = 4; c = Color.white; break; case L: squareCoords[0] = new Point(1, 0); squareCoords[1] = new Point(1, 1); squareCoords[2] = new Point(1, 2); squareCoords[3] = new Point(2, 2); s = 3; c = Color.blue; break; case O: squareCoords[0] = new Point(0, 0); squareCoords[1] = new Point(0, 1); squareCoords[2] = new Point(1, 0); squareCoords[3] = new Point(1, 1); s = 2; c = Color.cyan; break; 426 J a v a P r o g r am m i n g f o r t h e A b s o l ut e B e gi n n e r JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 426 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. case R: squareCoords[0] = new Point(1, 0); squareCoords[1] = new Point(2, 0); squareCoords[2] = new Point(1, 1); squareCoords[3] = new Point(1, 2); s = 3; c = Color.red; break; case S: squareCoords[0] = new Point(1, 1); squareCoords[1] = new Point(1, 2); squareCoords[2] = new Point(2, 0); squareCoords[3] = new Point(2, 1); s = 3; c = Color.yellow; break; case T: squareCoords[0] = new Point(0, 1); squareCoords[1] = new Point(1, 1); squareCoords[2] = new Point(1, 2); squareCoords[3] = new Point(2, 1); s = 3; c = Color.green; break; case Z: squareCoords[0] = new Point(1, 0); squareCoords[1] = new Point(1, 1); squareCoords[2] = new Point(2, 1); squareCoords[3] = new Point(2, 2); s = 3; c = Color.magenta; break; default : squareCoords = new Point[1]; squareCoords[0] = new Point(0, 0); s = Block.MIN_SIZE; c = Color.orange; } return new Block(s, squareCoords, c); } } Summary In this chapter, you wrote a larger scale project than in any of the preceding chapters. You learned how to create custom event-handling models. You learned about inner classes, including anonymous inner classes. You also learned some file I/O. In building the Block Game application and the classes associated with it, you used many of the concepts you learned in previous chapters. In the next 427 C h a p t e r 11 C u s t o m E v e n t H a n d l i n g a n d F i l e I / O JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 427 TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... subclasses of Automobile The javadoc Utility The javadoc utility generates HTML documentation for your package classes You can run the javadoc utility on individual class files or entire packages You have to comment your code in a special way for this to work Here is an example of a javadoc comment, also known as a documentation comment /** * This is a javadoc comment */ A javadoc comment starts off...JavaProgAbsBeg-11.qxd 2/25/03 8:57 AM Page 428 Java Programming for the Absolute Beginner 428 chapter, you will learn how to create custom lightweight components, how to create your own custom packages, and also how to take advantage of the javadoc utility included with the Java SDK You will apply this knowledge to building another big... it takes JavaProgAbsBeg-12.qxd 2/25/03 8:58 AM Page 432 Java Programming for the Absolute Beginner 432 }); pack(); setVisible(true); } public static void main(String args[]) { new SwingTest(); } } You should pretty much be able to tell what is going on here just by reading the code because it is so similar to how the AWT works The JFrame class inherits from Frame and exists to offer support for the... are all Java code and don’t have native peers They work the same on all platforms Although Swing is not fully covered by this book, you already have a head start The concepts of the Swing components are similar to the concepts in the AWT package Take the following code for instance: /* * SwingTest * Demonstrates, very basically, how to use swing */ import javax.swing.*; import java. awt.*; import java. awt.event.*;... using the javadoc utility, how do you actually generate the documentation? At your command prompt, type the javadoc command using the following syntax: javadoc [options] [package-names] [source-files] TEAM LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark JavaProgAbsBeg-12.qxd 2/25/03 8:58 AM Page 437 437 TA B L E 1 2 2 JAVADOC... your packages • –version shows you how to make the javadoc utility include the version you specify using the @version javadoc command The author and version information are left out by default even if the tags are in the source file’s javadoc comments A more real example is: javadoc –d docs –author -version pkg.mypackage This generates the documentation for a package named pkg.mypackage The documentation... Chapter 12 and some of them are listed in Table 12.1 If you need to review these event types, refer to Chapter 7, “Advanced GUI: Layout Managers and Event Handling.” JavaProgAbsBeg-12.qxd 2/25/03 8:58 AM Page 434 Java Programming for the Absolute Beginner 434 You declare an ActionListener—here it’s named actionListener—and then provide the addActionListener(ActionListener) method Inside of that method,... to import the class later JavaProgAbsBeg-12.qxd 2/25/03 8:58 AM Page 436 Java Programming for the Absolute Beginner 436 Notice that the drive() method is declared abstract It has no body, and as you saw in the previous chapter, that’s how you create an abstract method Any nonabstract subclass of Automobile must provide the body for this method Also notice that there is a non-abstract method here too:... LinG - Live, Informative, Non-cost and Genuine! Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark JavaProgAbsBeg-12.qxd 2/25/03 8:58 AM Page 431 431 Creating Lightweight Components No, not schwing, Garth, Swing! Take your Ritalin The Swing package (javax.swing) provides a set of lightweight components Swing is included with the standard edition of the Java 2 platform Its components... such a way that you can run the javadoc utility to generate documentation for your packages The main goals of this chapter include the following concepts: • Declare packages • Create lightweight components • Create and extend abstract classes • Use javadoc comments and run the javadoc tool • Create the MinePatrol game by importing the custom packages TEAM LinG - Live, Informative, Non-cost and Genuine! . source code for ScoreInfoPanel .java: /* * ScoreInfoPanel * A Panel that shows the scoring info for a BlockGame * and shows the next block. */ import java. awt.*; import java. io.*; import java. text.NumberFormat; public. straight-forward, such as laying out these components. However, the use of the NumberFormat class needs some explanation. NumberFor- mat is part of the java. text package. It helps you format numbers Here is the full source code listing for BlockGame .java: /* * Block Game * The actual Application Frame for the Block Game. */ import java. awt.*; import java. awt.event.*; public class BlockGame