Writing and Reading Bytes
Document files don't really contain text. Image files don't really contain pictures. MP3 files don't really contain music, and MPEG files don't really contain movies. They all contain bytes, because all files just contain bytes. The bytes encode information; they are decoded by software appropriate to the encoded content. This is why filename extensions are so important. They tell the computer what decoding software to use. If you take an image file that encodes a really beautiful picture and you change filename extension to .mp3, it's probably going to sound terrible.
All files are sequences of bytes. Before we look at decoding and encoding the information represented by the files, you need to learn how to write and read plain ordinary bytes. You will make extensive use of two of the classes in the java.io package:
-
FileOutputStream
-
FileInputStream
A file output stream writes bytes to a file; a file input stream reads bytes from a file. Our purpose here is not to present both classes in their entirety. Here you will learn more than enough to be able to use them well. Whenever you want to complete your understanding, you can refer to the API documentation.
Backslashes in Filenames
If you want to write bytes to a file in the current working directory called xyz, you can construct a file output stream like this:
FileOutputStream fos;
fos = new FileOutputStream("xyz");
Of course, you can create a file output stream in a similar way. Ignoring for the moment the issue of what you can actually do with those streams, you have to deal with the question of what happens when you want to specify a full pathname on a Windows system. For example, what if you want to write to a file whose full pathname is C:my_files\photos\abc? The following code will not do what you want:
FileOutputStream fos;
fos = new FileOutputStream("C:my_files\photos\abc");
Surprisingly, this code will not compile! The compiler error says that there is an invalid escape character, whatever that means.
Actually, the problem has nothing to do with file output streams. It has to do with backslashes in literal strings. You would get the same compilation error if you tried the following:
String s = "C:my_files\photos\abc";
Writing and Reading Data
At this point, you might be asking yourself, "When would I ever want to write or read bytes?" After all, one of the huge disadvantages of SimCom, as compared to the JVM, is that it deals only in bytes, while Java supports eight primitive data types and limitless class types.
The answer, fortunately, is that you never have to write or read bytes if you don't want to. You still have to create file input and output streams, and you still have to close them when you're done using them, but you don't have to write to them or read from them. Not directly, anyway. The writing and reading can be done by two very useful classes in the java.io package:
-
DataOutputStream
-
DataInputStream
Painting
Painting
There are many reasons why a frame's contents may need to be redrawn:
-
The frame has become visible for the first time.
-
The contents have changed due to user input (as when you moved a scrollbar in Color Lab).
-
The frame has deiconified.
-
The frame has moved to the front of the desktop, after having been covered or partially covered by another frame.
When any of these occur, the underlying windowing software notifies the frame, and a call is made to the frame's paint() method. The great thing about this arrangement is that you never have to detect these changes to the frame. The environment takes care of all that for you. All you have to do is subclass Frame and provide a paint() method that draws the frame's interior. In other words, you have to think about what to paint, but you don't have to think about when to paint.
Drawing and Filling with a Graphics Object
The shapes that you can draw with the Graphics class include the following:
-
Lines
-
Squares and rectangles
-
Circles and ovals
1. import java.awt.*;
2.
3. public class BlackLineOnWhite extends Frame
4. {
5. BlackLineOnWhite()
6. {
7. setSize(150, 180);
8. }
9.
10. public void paint(Graphics g)
11. {
12. g.setColor(Color.black);
13. g.drawLine(60, 115, 120, 70);
14. }
15.
16. public static void main(String[] args)
17. {
18. BlackLineOnWhite blonw = new BlackLineOnWhite();
19. blonw.setVisible(true);
20. }
1. import java.awt.*;
2.
3. public class BlueRect extends Frame
4. {
5. BlueRect ()
6. {
7. setSize(150, 180);
8. }
9.
10. public void paint(Graphics g)
11. {
12. g.setColor(Color.blue);
13. g.drawRect(25, 50, 100, 35);
14. }
15.
16. public static void main(String[] args)
17. {
18. BlueRect br = new BlueRect();
19. br.setVisible(true);
20. }
1. import java.awt.*;
2.
3. public class FontAndBaseline extends Frame
4. {
5. FontAndBaseline()
6. {
7. setSize(200, 150);
8. }
9.
10. public void paint(Graphics g)
11. {
12. int x = 25;
13. int yBaseline = 100;
14. g.setColor(Color.lightGray);
15. g.drawLine(x, yBaseline, 125, yBaseline);
16. g.setColor(Color.black);
17. g.drawString("just a gaping quay", x, yBaseline);
18. }
19.
20.
21. public static void main(String[] args)
22. {
23. FontAndBaseline fabl = new FontAndBaseline();
24. fabl.setVisible(true);
25. }
26. }
Layout Managers
The java.awt package contains a very useful class called Container. Generally, you don't instantiate this class directly. Rather, you instantiate its various subclasses, which include Frame. All containers have the following properties:
-
They are rectangular.
-
They can contain other components, including other containers.
-
They use layout managers to determine the locations and positions of the components they contain.
The great thing about layout managers is that you don't have to think about the details of component layout. Each layout manager class imposes a different layout policy on the container it manages. All you have to do is become familiar with the various layout policies available to you. The layout manager will take care of the details.
No comments:
Post a Comment