HelloJava2 newobj = new HelloJava2(”Hello, Java!”); Container content = f.getContentPane( ); content.add(newobj); The first line is the important one, where a new HelloJava2 object is created. The HelloJava2 constructor takes a String as an argument and, as it turns out, uses it to set the message that is displayed in the window. A class could also provide methods that allow us to configure an object manually after it’s created or to change its configuration at a later time. Many classes do both; the constructor simply takes its arguments and passes them to the appropriate methods or variables. The HelloJava2 class, for example, could have a public method, setMessage( ), that allowed us to set the message at any time. Constructors with parameters are therefore a convenience that allows a sort of shorthand to set up a new object. HelloJava2’s constructor does two things: it sets the text of the theMessage instance variable, and it tells the system “Hey, I’m interested in anything that happens involving the mouse”: public HelloJava2(String message) { theMessage = message; addMouseMotionListener(this); } So what, you may ask, is the type of the argument to the HelloJava2 constructor, back in the main( ) method? It, too, is a String. With a little magic from the Java compiler, quoted strings in Java source code are turned into String objects. A bit of funny business is going on here, but it’s simply for convenience. (See Chapter 9, for a complete discussion of the String class.) We can use a special read-only variable, called this , to explicitly refer to our object. A method can use this to refer to the instance of the object that holds it. The following two statements are therefore equivalent ways to assign a value to an instance variable: theMessage = message; or: this.theMessage = message; We’ll always use the shorter, implicit, form to refer to instance variables. But we’ll need the this variable when we have to pass a reference to our object to a method in another class. We often do this so that methods in other classes can invoke our public methods (a callback, explained later in this chapter) or use our public variables. The other method that we call in HelloJava2’s constructor is addMouse-MotionListener( ). This method is part of the event mechanism, which we discuss next. 2.2.4 Events The last two methods of HelloJava2 let us get information from the mouse. Each time the user performs an action, such as pressing a key on the keyboard, moving the mouse, or perhaps banging his or her head against a touch-sensitive screen, Java generates an event. An event represents an action that has occurred; it contains information about the action, such as its time and location. Most events are associated with a particular graphical user interface (GUI) component in an application. A keystroke, for instance, could correspond to a character being typed into a particular text entry field. Pressing a mouse button could activate a particular button on the screen. Even just moving the - 37
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
String theMessage; messageX and messageY are integers that hold the current coordinates of our movable message. They are initialized to default values, which should place the message somewhere near the center of the window. Java integers are always 32-bit signed numbers. There is no fretting about what architecture your code is running on; numeric types in Java are precisely defined. The variable theMessage is of type String and can hold instances of the String class. You should note that these three variables are declared inside the braces of the class definition, but not inside any particular method in that class. These variables are called instance variables or member variables because they belong to the entire class, and copies of them appear in each separate instance of the class. Instance variables are always visible (usable) in any of the methods inside their class. Depending on their modifiers, they may also be accessible from outside the class. Unless otherwise initialized, instance variables are set to a default value of 0 (zero), false, or null. Numeric types are set to zero, boolean variables are set to false, and class type variables always have their value set to null, which means “no value.” Attempting to use an object with a null value results in a runtime error. Instance variables differ from method arguments and other variables that are declared inside of a single method. The latter are called local variables. They are effectively private variables that can be seen only by code inside the method. Java doesn’t initialize local variables, so you must assign values yourself. If you try to use a local variable that has not yet been assigned a value, your code will generate a compile-time error. Local variables live only as long as the method is executing and then disappear (which is fine, since nothing outside of the method can see them anyway). Each time the method is invoked, its local variables are recreated and must be assigned values. We have made some changes to our previously stodgy paintComponent( ) method. All of the arguments in the call to drawString( ) are now variables. 2.2.3 Constructors The HelloJava2 class includes a special kind of a method called a constructor. A constructor is called to set up a new instance of a class. When a new object is created, Java allocates storage for it, sets instance variables to their default values, and then calls the constructor method for the class to do whatever application-level setup is required. A constructor method is a method with the same name as its class. For example, the constructor for the HelloJava2 class is called HelloJava2( ). Constructors don’t have a return type; by definition, they return an object of that class. But like other methods, constructors can take arguments. Their sole mission in life is to configure and initialize newly born class instances, possibly using information passed to them in parameters. An object is created by using the new operator with the constructor for the class and any necessary arguments. The resulting object instance is returned as a value. In our example, a new HelloJava2 is created in the main( ) method, in this line: f.getContentPane( ).add(new HelloJava2(”Hello, Java!”)); This line actually does three things. The following lines are equivalent, and a little easier to understand: - 36
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
Place the text of this example in a file called HelloJava2.java and compile it as before. You should get a new class file, HelloJava2.class, as a result. To run the new example, use the following command line: % java HelloJava2 Feel free to substitute your own salacious comment for the “Hello, Java!” message, and enjoy many hours of fun, dragging the text around with your mouse. 2.2.1 The import Statement So, what have we added? First you may notice that a few lines are now hovering above our class: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class HelloJava2 … The import statement lists external classes to use in this file and tells the compiler where to look for them. In our first example, we designated the JComponent class as the superclass of HelloJava1. JComponent was not defined by us, and the compiler therefore had to look elsewhere for it. In that case, we referred to JComponent by its fully qualified name, which is javax.swing.JComponent. The JComponent class and all the other classes in the javax.swingpackage are stored in a standard location, known to the compiler. In this example, the statement import javax.swing.* enables us to refer to all the classes in the javax.swing package by their simple names. For example, we don’t have to use fully qualified names to refer to the JComponent and JFrame classes. Our current example uses only the Graphics class from the java.awt package. So we could have used import java.awt.Graphics instead of using the wildcard * to import all of the AWT package’s classes. However, we are anticipating using several more classes from this package in the upcoming examples. We also import all the classes from the package java.awt.event ; these classes provide the Event objects that we use to communicate with the user. By listening for events, we find out when the user moved the mouse, clicked a button, and so on. Notice that importing java.awt.* doesn’t automatically import the event package. The asterisk imports only the classes in a particular package, not other packages. Packages don’t contain other packages, even if the hierarchical naming scheme would seem to imply such a thing. The import statement may seem a bit like the C or C++ preprocessor #include statement, which injects header files into programs at the appropriate places. This is not true; there are no header files in Java. The import statement does not copy any code into a source file. It’s just a convenience. Think of it as “introducing” one or more external classes to the compiler; after they’ve been introduced, you can call them by their simple names, instead of by their fully-qualified names. 2.2.2 Instance Variables We have added some variables to our example: int messageX = 125, messageY = 95; - 35
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
2.2 HelloJava2: The Sequel Let’s make our application a little more interactive, shall we? The following improvement, HelloJava2 , allows us to drag the message around with the mouse. HelloJava2 is a new application another subclass of the JComponent class. In that sense, it’s a sibling of HelloJava1. Having just seen inheritance at work, you might wonder why we aren’t creating a subclass of HelloJava1 and exploiting inheritance to build upon our previous example and extend its functionality. Well, in this case, that would not necessarily be an advantage, and for clarity we simply start over.[3] [3] You are left to consider whether such subclassing would even make sense. Should HelloJava2 really be a kind of HelloJava? Are we looking for refinement or just code reuse? Here is HelloJava2: //file: HelloJava2.javaimport java.awt.*; import java.awt.event.*; import javax.swing.*; public class HelloJava2extends JComponent implements MouseMotionListener { // Coordinates for the message int messageX = 125, messageY = 95; String theMessage; public HelloJava2(String message) { theMessage = message; addMouseMotionListener(this); } public void paintComponent(Graphics g) { g.drawString(theMessage, messageX, messageY); } public void mouseDragged(MouseEvent e) { // Save the mouse coordinates and paint the message. messageX = e.getX( ); messageY = e.getY( ); repaint( ); } public void mouseMoved(MouseEvent e) {} public static void main(String[] args) { JFrame f = new JFrame(”HelloJava2″); // Make the application exit when the window is closed. f.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent we) { System.exit(0); } }); f.setSize(300, 300); f.getContentPane( ).add(new HelloJava2(”Hello, Java!”)); f.setVisible(true); } } Two slashes in a row indicates that the rest of the line is a comment. We’ve added a few comments to HelloJava2 to help you keep track of everything. - 34
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services
Some other notable core packages include: java.lang, which contains fundamental classes needed by the Java language itself; java.awt, which contains classes of the pre-Java 2 Abstract Window Toolkit; and java.net, which contains the networking classes. A few classes contain methods that are not written in Java, but are instead part of the native Java implementation on a particular platform. These are the only classes that have to be ported to a new platform. They form the basis for all interaction with the operating system. All other classes are built on or around these and are completely platform-independent. 2.1.9 The paintComponent( ) Method The source for our HelloJava1 class defines a method, paintComponent( ) , that overrides the paintComponent( ) method from the JComponent class: public void paintComponent(java.awt.Graphics g) { g.drawString(”Hello, Java!”, 125, 95); } The paintComponent( ) method is called when it’s time for our example to draw itself on the screen. It takes a single argument, a Graphics object, and doesn’t return any type of value (void) to its caller. Modifiers are keywords placed before classes, variables, and methods to alter their accessibility, behavior, or semantics. paintComponent( ) is declared as public , which means it can be invoked (called) by methods in classes other than HelloJava1. In this case, it’s the Java windowing environment that is calling our paintComponent( ) method. A method or variable declared as private is inaccessible from outside of its class. The Graphics object, an instance of the Graphics class, represents a particular graphical drawing area. (It is also called a graphics context.) It contains methods that can be used to draw in this area, and variables that represent characteristics such as clipping or drawing modes. The particular Graphics object we are passed in the paintComponent( ) method corresponds to our component’s area of the screen. The Graphics class provides methods for rendering shapes, images, and text. In HelloJava1, we invoke the drawString( ) method of our Graphics object to scrawl our message at the specified coordinates. (For a description of the methods available in the Graphics class, see Chapter 17.) As in C++, a method or variable of an object is accessed in a hierarchical way by appending a dot (.) and its name to the object that holds it. We invoked the drawString( ) method of the Graphics object (referenced by our g variable) in this way: g.drawString(”Hello, Java!”, 125, 95); You may need to get used to the idea that our application is drawn by a method that is called by an outside agent at arbitrary times. How can we do anything useful with this? How do we control what gets done and when? These answers will be forthcoming. For now, just think about how you would structure applications that draw themselves on command. - 33
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
In this sense, a HelloJava1 object is a kind of JComponent, which is a kind of Container, and each of these can ultimately be considered to be a kind of Component. It’s from these classes that HelloJava1 inherits its basic graphical user interface functionality and the ability to have other graphical components embedded within it. Component is a subclass of the top-level Object class, so all of these classes define kinds of Objects. Every other class in the Java API inherits behavior from Object, which defines a few basic methods, as you’ll see in Chapter 7. We’ll continue to use the word object (lowercase o) in a generic way to refer to an instance of any class; we’ll use Object to refer specifically to that class. 2.1.8 Packages In our previous example, the JComponent class is referenced by its fully qualified name javax.swing.JComponent: public class HelloJava1 extends javax.swing.JComponent {…} The prefix on the class name identifies it as belonging to the javax.swing package. Packages provide a means for organizing Java classes. A package is a group of Java classes that are related by purpose or by application. Classes in the same package have special access privileges with respect to one another and may be designed to work together. Package names are hierarchical and are used somewhat like Internet domain and host names, to distinguish groups of classes by organization and application. Classes may be dynamically loaded over networks from arbitrary locations; within this context, packages provide a crude namespace of Java classes.[2] [2] There are many efforts under way to find a general solution to the problem of locating resources in a globally distributed computing environment. The Uniform Resource Identifier Working Group of the IETF has proposed Uniform Resource Names (URNs). A URN would be a more abstract and persistent identifier that would be resolved to a URL through the use of a name service. We can imagine a day when there will exist a global namespace of trillions of persistent objects forming the infrastructure for all computing resources. Java provides an important evolutionary step in this direction. javax.swing identifies a particular package that contains classes related to Swing, Java 2’s fancy graphical user interface toolkit. javax.swing.JComponent identifies a specific class, the JComponent class, within that package. The java. hierarchy is special. Any package that begins with java. is part of the core Java API and is available on any platform that supports Java. While javax normally denotes a standard extension to the core platform, javax.swing is an exception it really is part of the core API. Figure 2.3 illustrates some of the core Java packages, showing a representative class or two from each. Figure 2.3. Some core Java packages - 32
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services
2.1.6 The JComponent Class The JComponent class provides the framework for building user interface components (called controls or widgets in other windowing systems). Particular components, such as buttons, labels, and list boxes, are implemented as subclasses of JComponent. We override methods in such a subclass to implement the behavior of our particular component. This may sound restrictive, as if we are limited to some predefined set of routines, but that is not the case at all. Keep in mind that the methods we are talking about are means of interacting with the windowing system. A realistic application might involve hundreds or even thousands of classes, with legions of methods and variables and multiple threads of execution. The vast majority of these are related to the particulars of our job. The inherited methods of the JComponent class, and of other predefined classes, serve as a framework on which to hang code that handles certain types of events and performs special tasks. The paintComponent( ) method is an important method of the JComponent class; we override it to implement the way our particular component displays itself on the screen. The default behavior of paintComponent( ) doesn’t do any drawing at all; here, we’re overriding paintComponent( ) to do something interesting. We don’t override any of the other inherited members of JComponentbecause they provide basic functionality and reasonable defaults for this (trivial) example. As HelloJava grows, we’ll delve deeper into the inherited members and use additional methods. We will also add some application-specific methods and variables for the needs of HelloJava. JComponent is really the tip of another iceberg called SwingSwing. Swing is Java’s user interface toolkit; we’ll discuss it in some detail in Chapter 13 through Chapter 18. 2.1.7 Relationships and Finger Pointing We can correctly refer to HelloJava1 as a JComponent because subclassing can be thought of as creating an “is a” relationship, in which the subclass is a kind of its superclass. HelloJava1 is therefore a kind of JComponent. When we refer to a kind of object, we mean any instance of that object’s class or any of its subclasses. Later, we will look more closely at the Java class hierarchy and see that JComponent is itself a subclass of the Container class, which is further derived from a class called Component , and so on, as shown in Figure 2.2. Figure 2.2. Part of the Java class hierarchy - 31
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
method takes one argument named (somewhat tersely) g, which is of type Graphics. When the paintComponent( ) method is invoked, a Graphics object is assigned to g, which we use in the body of the method. We’ll say more about paintComponent( ) and the Graphics class in a moment. But first, a few words about variables. We have loosely referred to variables as holding objects. In reality, variables that have class types don’t so much contain objects as point to them. Class-type variables are references to objects. A reference is a pointer to or a name for an object. If you declare a class-type variable without assigning it to an object, it doesn’t point to anything. It’s assigned the default value of null, meaning “no value.” If you try to use a variable with a null value as if it were pointing to a real object, a runtime error (NullPointerException) occurs. Where do you get an instance of a class to assign to a variable in the first place? The answer is through the use of the new operator. We’ll examine object creation a little later in the chapter. 2.1.5 Inheritance Java classes are arranged in a parent-child hierarchy, in which the parent and child are known as the superclass and subclass, respectively. We’ll explore these concepts fully in Chapter 6. In Java, every class has exactly one superclass (a single parent), but possibly many subclasses. The only exception to this rule is the Object class, which sits atop the entire class hierarchy; it has no superclass. The declaration of our class in the previous example uses the keyword extends to specify that HelloJava1 is a subclass of the JComponent class: public class HelloJava1 extends javax.swing.JComponent {…} A subclass may be allowed to inherit some or all of the variables and methods of its superclass. Through inheritance, the subclass can use those variables and methods as if it has declared them itself. A subclass can add variables and methods of its own, and it can also override the meaning of inherited variables and methods. When we use a subclass, overridden variables and methods are hidden (replaced) by the subclass’s own versions of them. In this way, inheritance provides a powerful mechanism whereby a subclass can refine or extend its superclass. For example, the hypothetical spreadsheet class might be subclassed to produce a new scientific spreadsheet class with extra mathematical functions and special built-in constants. In this case, the source code for the scientific spreadsheet might declare methods for the added mathematical functions and variables for the special constants, but the new class automatically has all the variables and methods that constitute the normal functionality of a spreadsheet; they are inherited from the parent spreadsheet class. This means the scientific spreadsheet maintains its identity as a spreadsheet, and we can use it anywhere the simpler spreadsheet is used. Our HelloJava1 class is a subclass of the JComponent class and inherits many variables and methods not explicitly declared in our source code. These members operate in the same way as the ones we add or override. - 30
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services
f.getContentPane().add(new HelloJava1( )); Here, we’re actually creating a new HelloJava1 object and placing it inside the JFrame we just created. main( )’s final task is to show the frame window and its contents, which otherwise would be invisible. An invisible window makes for a pretty boring application. f.setVisible(true); That’s the whole main( ) method. As we progress through the examples in this chapter, it will remain mostly unchanged as the HelloJava class evolves around it. Let’s get started! 2.1.3 Classes and Objects A class is a blueprint for a part of an application; it lists methods and variables that go into making up that part. Many individual working copies of a given class can exist while an application is active. These individual incarnations are called instances of the class, or objects. Two instances of a given class may contain different data, but they always have the same methods. As an example, consider a Button class. There is only one Button class, but an application can create many different Button objects, each one an instance of the same class. Furthermore, two Button instances might contain different data, perhaps giving each a different appearance and performing a different action. In this sense, a class can be considered a mold for making the object it represents: something like a cookie cutter stamping out working instances of itself in the memory of the computer. As you’ll see later, there’s a bit more to it than that a class can in fact share information among its instances but this explanation suffices for now. Chapter 5, has the whole story on classes and objects. The term object is very general and in some other contexts is used almost interchangeably with class. Objects are the abstract entities all object-oriented languages refer to in one form or another. We will use object as a generic term for an instance of a class. We might, therefore, refer to an instance of the Button class as a Button, a Button object, or, indiscriminately, as an object. The main( ) method in the previous example creates a single instance of the HelloJava1 class and shows it in an instance of the JFrame class. You could modify main( ) to create many instances of HelloJava1, perhaps each in a separate window. 2.1.4 Variables and Class Types In Java, every class defines a new type (data type). A variable can be of this type and then hold instances of that class. A variable could, for example, be of type Button and hold an instance of the Button class, or of type SpreadSheetCell and hold a SpreadSheetCell object, just as it could be any of the more familiar types such as int or float. Ignoring the main( ) method for the moment, there is only one variable in our simple HelloJava example. It’s found in the declaration of the paintComponent( ) method: public void paintComponent(java.awt.Graphics g) {…} Just like functions in C (and many other languages), a method in Java declares a list of variables that hold its arguments, and it specifies the types of those arguments. Our paintComponent( ) - 29
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services
2.1.1 Classes The previous example defines a class named HelloJava1. Classes are the fundamental building blocks of most object-oriented languages. A class in Java is very much like a class in C++, and somewhat like a struct in C. It’s a group of data items, with associated functions that perform operations on this data. The data items in a class are called fields or variables ; the functions are called methods . A class might represent something concrete, like a button on a screen or the information in a spreadsheet, or it could be something more abstract, such as a sorting algorithm or possibly the sense of ennui in your MUD character. A hypothetical spreadsheet class might, for example, have variables that represent the values of its individual cells and methods that perform operations on those cells, such as “clear a row” or “compute values.” We’ll talk more about this in a little while. Our HelloJava1 class contains an entire Java application. It holds two general types of variables and methods: those we need for our specific application’s tasks and some special predesignated ones we provide to interact with the outside world. The Java runtime system, in this case the javacommand-line tool, calls methods in HelloJava1 to pass us information and prod us to perform actions. Our simple HelloJava1 class implements two important methods. The first, main( ), is called when the application is first started. We’ll talk more about it in the next section. The second method, paintComponent( ), is called by Java when it’s time for our application to draw itself on the screen. 2.1.2 The main( ) Method When you run our example, what really happens? The java command looks in the HelloJava1 class to see if it contains a special method called main( ) . If it does, this method is run. The main( ) method is simply an entry point for an application. It’s a piece of code that you want to be run when the application first starts. The main( ) method sets up a window (a JFrame) that will contain the visual output of the HelloJava1 class. What really interests us here is not the main( ) method but the rest of the class. We’ll go through several incarnations of this class, adding features and methods. But the main( ) method will remain largely unchanged, keeping its basic function of creating a window that holds the HelloJava example. Let’s quickly walk through the main( ) method, just so you know what it does. First, main( ) creates a JFrame, a window that will hold our example: javax.swing.JFrame f = new javax.swing.JFrame(”HelloJava1″); The new word in this line of code is tremendously important: javax.swing.JFrame ( just JFrame for short) is the name of a class that represents a window you can see on your screen. The class itself is just a template, like a building plan. The new keyword tells Java to allocate memory and initialize a new JFrame object. When frame windows are first created, they are very small. Our next task is to set the size to something reasonable: f.setSize(300, 300); Then we create our actual example and put it inside the frame window: - 28
Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost JSP Web Hosting services