CHAPTER GOALS
To learn about variables
To understand the concepts of classes and objects
To be able to call methods
To learn about parameters and return values
To be able to browse the API documentation
T To implement test programs
To understand the difference between objects and object references
G To write programs that display simple shapes
Most useful programs don't just manipulate numbers and strings. Instead, they deal with data items that are more complex and that more closely represent1 entities in the real world. Examples of these data items include bank accounts, employee records, and graphical shapes.
The Java language is ideally suited for designing and manipulating such data items, or objects. In Java, you implement classes that describe the behavior of these objects. In this chapter, you will learn how to manipulate objects that belong to classes that have already been implemented. This knowledge will prepare you for the next chapter in which you will learn how to implement your own classes.
Before we start with the main topic of this chapter, we need to go over some basic programming terminology. In the first three sections of this chapter, you will learn about the concepts of types, variables, and assignment.
A computer program processes values: numbers, strings, and more complex data items. In Java, every value has a type. For example, the number 13 has the type int
(an abbreviation for "integer"), "Hello, World"
has the type String
, and the object System.out
has the type PrintStream
. The type tells you what operations you can carry out with the values. For example, you can compute the sum or product of any two integers. You can call println
on any object of type PrintStream
.
A type specifies a set of values and the operations that can be carried out with the values.
Java has separate types for integers and floating-point numbers. Integers are whole numbers; floating-point numbers can have fractional parts. For example, 13 is an integer and 1.3 is a floating-point number.
The name "floating-point" describes the representation of the number in the computer as a sequence of the significant digits and an indication of the position of the decimal point. For example, the numbers 13000.0, 1.3, 0.00013 all have the same decimal digits: 13. When a floating-point number is multiplied or divided by 10, only the position of the decimal point changes; it "floats". This representation is related to the "scientific" notation 1.3 × 10−4. (Actually, the computer represents numbers in base 2, not base 10, but the principle is the same.)
If you need to process numbers with a fractional part, you should use the type called double
, which stands for "double precision floating-point number". Think of a number in double
format as any number that can appear in the display panel of a calculator, such as 1.3 or −0.333333333.
The double
type denotes floating-point numbers that can have fractional parts.
Table 2.1. Number Literals in Java
When a value such as 13
or 1.3
occurs in a Java program, it is called a number literal. Do not use commas when you write number literals in Java. For example, 13,000 must be written as 13000
. To write numbers in exponential notation in Java, use the notation E
n instead of "×10n". For example, 1.3×10–4 is written as 1.3E-4
. Table 1 shows how to write integer and floating-point literals in Java.
You may wonder why Java has separate integer and floating-point number types. Pocket calculators don't need a separate integer type; they use floating-point numbers for all calculations. However, integers have several advantages over floating-point numbers. They take less storage space, are processed faster, and don't cause rounding errors. You will want to use the int
type for quantities that can never have fractional parts, such as the length of a string. Use the double
type for quantities that can have fractional parts, such as a grade point average.
There are several other number types in Java that are not as commonly used. We will discuss these types in Chapter 4. For most programs in this book, however, the int
and double
types are all you need for processing numbers.
In Java, the number types are primitive types, and numbers are not objects.
In Java, the number types (int, double
, and the less commonly used types) are primitive types. Numbers are not objects. The number types have no methods.
However, you can combine numbers with operators such as +
and -
, as in 10 + n
or n - 1
. To multiply two numbers, use the *
operator. For example, 10 × n is written as 10 * n
.
A combination of variables, literals, operators, and/or methods (which you will see in Section 2.4) is called an expression. A typical example of an expression is
x + y * 2
As in mathematics, the *
operator binds more strongly than the +
operator. That is, x + y * 2
means the sum of x
and y * 2
. If you want to multiply the sum of x
and y
by 2, use parentheses:
(x + y) * 2
Numbers can be combined by arithmetic operators such as +, -
, and *
.
2. Which number type would you use for storing the area of a circle?
3. Why is the expression 13.println()
an error?
4. Write an expression to compute the average of the values x
and y
.
You often want to store values so that you can use them at a later time. To remember a value, you need to hold it in a variable. A variable is a storage location in the computer's memory that has a type, name, and contents. For example, here we declare three variables:
String greeting = "Hello, World!"; PrintStream printer = System.out; int width = 20;
You use variables to store values that you want to use at a later time. A variable has a type, a name, and a value.
The first variable is called greeting
. It can be used to store String
values, and it is set to the value "Hello, World!"
. The second variable, printer
, stores a PrintStream
value, and the third stores an integer.
Variables can be used in place of the values that they store:
printer.println(greeting); // Same as System.out.println("Hello, World!") printer.println(width); // Same as System.out.println(20)
When you declare your own variables, you need to make two decisions.
What type should you use for the variable?
What name should you give the variable?
The type depends on the intended use. If you need to store a string, use the String
type for your variable. If you need a number, choose the int
or double
type.
It is an error to store a value whose type does not match the type of the variable. For example, the following is an error:
String greeting = 20; // ERROR: Types don't match
Table 2.2. Variable Declarations in Java
Variable Name | Comment |
---|---|
| Declares an integer variable and initializes it with 10. |
| The initial value can depend on other variables. (Of course, |
Error: The type is missing. This statement is not a declaration but an assignment of a new value to an existing variable—see Section 2.3. | |
Error: You cannot initialize a number with a string. | |
| Declares two integer variables in a single statement. In this book, we will declare each variable in a separate statement. |
You cannot use a String
variable to store an integer. The compiler checks type mismatches to protect you from errors.
When deciding on a name for a variable, you should make a choice that describes the purpose of the variable. For example, the variable name greeting
is a better choice than the name g
.
Identifiers for variables, methods, and classes are composed of letters, digits, and the underscore character.
An identifier is the name of a variable, method, or class. Java imposes the following rules for identifiers:
Identifiers can be made up of letters, digits, and the underscore (_
) and dollar sign ($
) characters. They cannot start with a digit, though.
You cannot use spaces or symbols such as ?
or %
.
Furthermore, you cannot use reserved words, such as public
, as names; these words are reserved exclusively for their special Java meanings. (See Appendix C for all reserved words in Java.)
These are firm rules of the Java language. If you violate one of them, the compiler will report an error. Moreover, there are a couple of conventions that you should follow so that other programmers will find your programs easy to read:
Variable and method names should start with a lowercase letter. It is OK to use an occasional uppercase letter, such as farewellMessage
. This mixture of lowercase and uppercase letters is sometimes called "camel case" because the uppercase letters stick out like the humps of a camel.
Class names should start with an uppercase letter. For example, Greeting
would be an appropriate name for a class, but not for a variable.
You should not use the $
symbol in names. It is intended for names that are automatically generated by tools.
By convention, variable names should start with a lowercase letter.
If you violate these conventions, the compiler won't complain, but you will confuse other programmers who read your code.
Table 2.3. Variable Names in Java
Comment | |
---|---|
| Use "camel case" for variable names consisting of multiple words. |
| In mathematics, you use short variable names such as x or y. This is legal in Java, but not very common, because it can make programs harder to understand. |
Caution: Variable names are case-sensitive. This variable name is different from | |
Error: Variable names cannot start with a number. | |
Error: Variable names cannot contain spaces. | |
Error: You cannot use a reserved word as a variable name. |
Table 3 shows examples of legal and illegal variable names in Java.
Greeting1 g void 101dalmatians Hello, World <greeting>
6. Declare a variable to hold your name. Use camel case in the variable name.
You can change the value of a variable with the assignment operator (=
). For example, consider the variable declaration
int width = 10;
Use the assignment operator (=
) to change the value of a variable.
If you want to change the value of the variable, simply assign the new value:
width = 20;
The assignment replaces the original value of the variable (see Figure 1).
It is an error to use a variable that has never had a value assigned to it. For example, the following assignment statement has an error:
int height; width = height; // ERROR—uninitialized variable height
The compiler will complain about an "uninitialized variable" when you use a variable that has never been assigned a value. (See Figure 2.)
The remedy is to assign a value to the variable before you use it:
int height = 30; width = height; // OK
All variables must be initialized before you access them.
Or, even better, initialize the variable when you declare it.
int height = 30; int width = height; // OK
The right-hand side of the =
symbol can be a mathematical expression. For example,
width = height + 10;
This means "compute the value of height + 10
and store that value in the variable width
".
In the Java programming language, the =
operator denotes an action, to replace the value of a variable. This usage differs from the mathematical usage of the = symbol, as a statement about equality. For example, in Java, the following statement is entirely legal:
width = width + 10;
This means "compute the value of width + 10
In Java, it is not a problem that the variable width
is used on both sides of the =
symbol. Of course, in mathematics, the equation width = width + 10 has no solution.
8. How do you change the value of the greeting
variable to "Hello, Nina!"
?
We now come to the main purpose of this chapter: a closer understanding of objects. An object is a value that you can manipulate by calling one or more of its methods. A method consists of a sequence of instructions that can access the internal data of an object. When you call the method, you do not know exactly what those instructions are, or even how the object is organized internally. However, the behavior of the method is well-defined, and that is what matters to us when we use it.
Objects are entities in your program that you manipulate by calling methods.
For example, you saw in Chapter 1 that System.out
refers to an object. You manipulate it by calling the println
method. When the println
method is called, some activities occur inside the object, and the ultimate effect is that text appears in the console window. You don't know how that happens, and that's OK. What matters is that the method carries out the work that you requested.
A method is a sequence of instructions that accesses the data of an object.
Figure 4 shows a representation of the System.out
object. The internal data is symbolized by a sequence of zeroes and ones. Think of each method (symbolized by the gears) as a piece of machinery that carries out its assigned task.
In Chapter 1, you encountered two objects:
System.out
"Hello, World!"
The type of an object is a class. The System.out
object belongs to the class Print-Stream
. The "Hello, World!"
object belongs to the class String
. A class specifies the methods that you can apply to its objects.
You can use the println
method with any object that belongs to the PrintStream
class. System.out
is one such object. It is possible to obtain other objects of the Print-Stream
class. For example, you can construct a PrintStream
object to send output to a file. However, we won't discuss files until Chapter 11.
A class declares the methods that you can apply to its objects.
Just as the PrintStream
class provides methods such as println
and print
for its objects, the String
class provides methods that you can apply to String
objects. One of them is the length
method. The length
method counts the number of characters in a string. You can apply that method to any object of type String
. For example, the sequence of statements
String greeting = "Hello, World!"; int n = greeting.length();
sets n
to the number of characters in the String
object "Hello, World!"
. After the instructions in the length
method are executed, n
is set to 13. (The quotation marks are not part of the string, and the length
method does not count them.)
The length
method—unlike the println
method—requires no input inside the parentheses. However, the length
method yields an output, namely the character count.
In the next section, you will see in greater detail how to supply method inputs and obtain method outputs.
Let us look at another method of the String
class. When you apply the toUpperCase
method to a String
object, the method creates another String
object that contains the characters of the original string, with lowercase letters converted to uppercase. For example, the sequence of statements
String river = "Mississippi"; String bigRiver = river.toUpperCase();
sets bigRiver
to the String
object "MISSISSIPPI"
.
When you apply a method to an object, you must make sure that the method is declared in the appropriate class. For example, it is an error to call
System.out.length(); // This method call is an error
The PrintStream
class (to which System.out
belongs) has no length
method.
Let us summarize. In Java, every object belongs to a class. The class declares the methods for the objects. For example, the String
class declares the length
and toUpper-Case
methods (as well as other methods—you will learn about most of them in Chapter 4). The methods form the public interface of the class, telling you what you can do with the objects of the class. A class also declares a private implementation, describing the data inside its objects and the instructions for its methods. Those details are hidden from the programmers who use objects and call methods.
The public interface of a class specifies what you can do with its objects. The hidden implementation describes how these actions are carried out.
Figure 5 shows two objects of the String
class. Each object stores its own data (drawn as boxes that contain characters). Both objects support the same set of methods—the interface that is specified by the String
class.
Occasionally, a class declares two methods with the same name and different parameter types. For example, the PrintStream
class declares a second method, also called println
, as
public void println(int output)
That method is used to print an integer value. We say that the println
name is overloaded because it refers to more than one method.
10. How can you print out the uppercase version of "Hello, World!"
?
11. Is it legal to call river.println()
? Why or why not?
Methods are fundamental building blocks of Java programs. A program performs useful work by calling methods. In this section, we will examine how to provide inputs into a method, and how to obtain the result of the method.
Most methods require inputs that give details about the work that the method needs to do. For example, the println
method has an input: the string that should be printed. Computer scientists use the technical term parameter for method inputs. We say that the string greeting
is a parameter of the method call
System.out.println(greeting);
A parameter is an input to a method.
Figure 6 illustrates passing of the parameter to the method.
Technically speaking, the greeting
parameter is an explicit parameter of the println
method. The object on which you invoke the method is also considered a parameter of the method call; it is called the implicit parameter. For example, System.out
is the implicit parameter of the method call
System.out.println(greeting);
The implicit parameter of a method call is the object on which the method is invoked. All other parameters are explicit parameters.
Some methods require multiple explicit parameters, others don't require any explicit parameters at all. An example of the latter is the length
method of the String
class (see Figure 7). All the information that the length
method requires to do its job—namely, the character sequence of the string—is stored in the implicit parameter object.
The length
method differs from the println
method in another way: it has an output. We say that the method returns a value, namely the number of characters in the string. You can store the return value in a variable:
int n = greeting.length();
The return value of a method is a result that the method has computed for use by the code that called it.
You can also use the return value as a parameter of another method:
System.out.println(greeting.length());
The method call greeting.length()
returns a value—the integer 13. The return value becomes a parameter of the println
method. Figure 8 shows the process.
Not all methods return values. One example is the println
method. The println
method interacts with the operating system, causing characters to appear in a window. But it does not return a value to the code that calls it.
Let us analyze a more complex method call. Here, we will call the replace
method of the String
class. The replace
method carries out a search-and-replace operation, similar to that of a word processor. For example, the call
river.replace("issipp", "our")
constructs a new string that is obtained by replacing all occurrences of "issipp"
in "Mississippi"
with "our"
. (In this situation, there was only one replacement.) The method returns the String
object "Missouri"
. You can save that string in a variable:
river = river.replace("issipp", "our");
Or you can pass it to another method:
System.out.println(river.replace("issipp", "our"));
As Figure 9 shows, this method call has
one implicit parameter: the string "Mississippi"
two explicit parameters: the strings "issipp"
and "our"
a return value: the string "Missouri"
When a method is declared in a class, the declaration specifies the types of the explicit parameters and the return value. For example, the String
class declares the length
method as
public int length()
That is, there are no explicit parameters, and the return value has the type int. (For now, all the methods that we consider will be "public" methods—see Chapter 10 for more restricted methods.)
The type of the implicit parameter is the class that declares the method—String
in our case. It is not mentioned in the method declaration—hence the term "implicit".
The replace
method is declared as
public String replace(String target, String replacement)
To call the replace
method, you supply two explicit parameters, target
and replacement
, which both have type String
. The returned value is another string.
When a method returns no value, the return type is declared with the reserved word void
. For example, the PrintStream
class declares the println
method as
public void println(String output)
13. What is the result of the call river.replace("p", "s")
?
14. What is the result of the call greeting.replace("World", "Dave").length()
?
15. How is the toUpperCase
method declared in the String
class?
Most Java programs need to work on a variety of objects. In this section, you will see how to construct new objects. This allows you to go beyond String
objects and the System.out
object.
To learn about object construction, let us turn to another class: the Rectangle
class in the Java class library. Objects of type Rectangle
describe rectangular shapes—see Figure 10. These objects are useful for a variety of purposes. You can assemble rectangles into bar charts, and you can program simple games by moving rectangles inside a window.
Note that a Rectangle
object isn't a rectangular shape—it's an object that contains a set of numbers. The numbers describe the rectangle (see Figure 11). Each rectangle is described by the x- and y-coordinates of its top-left corner, its width, and its height.
It is very important that you understand this distinction. In the computer, a Rectangle
object is a block of memory that holds four numbers, for example x = 5, y = 10, width = 20, height = 30. In the imagination of the programmer who uses a Rectangle
object, the object describes a geometric figure.
To make a new rectangle, you need to specify the x, y, width, and height values. Then invoke the new
operator, specifying the name of the class and the parameters that are required for constructing a new object. For example, you can make a new rectangle with its top-left corner at (5, 10), width 20, and height 30 as follows:
new Rectangle(5, 10, 20, 30)
Use the new
operator, followed by a class name and parameters, to construct new objects.
Here is what happens in detail:
The process of creating a new object is called construction. The four values 5, 10, 20, and 30 are called the construction parameters.
The new
expression yields an object, and you need to store the object if you want to use it later. Usually you assign the output of the new
operator to a variable. For example,
Rectangle box = new Rectangle(5, 10, 20, 30);
Some classes let you construct objects in multiple ways. For example, you can also obtain a Rectangle
object by supplying no construction parameters at all (but you must still supply the parentheses):
new Rectangle()
This expression constructs a (rather useless) rectangle with its top-left corner at the origin (0, 0), width 0, and height 0.
17. The getWidth
method returns the width of a Rectangle
object. What does the following statement print?
System.out.println(new Rectangle().getWidth());
In this section we introduce a useful terminology for the methods of a class. A method that accesses an object and returns some information about it, without changing the object, is called an accessor method. In contrast, a method whose purpose is to modify the internal data of an object is called a mutator method.
An accessor method does not change the internal data of its implicit parameter. A mutator method changes the data.
For example, the length
method of the String
class is an accessor method. It returns information about a string, namely its length. But it doesn't modify the string at all when counting the characters.
The Rectangle
class has a number of accessor methods. The getX, getY, getWidth
, and getHeight
methods return the x- and y-coordinates of the top-left corner, the width, and the height values. For example,
double width = box.getWidth();
Now let us consider a mutator method. Programs that manipulate rectangles frequently need to move them around, for example, to display animations. The Rectangle
class has a method for that purpose, called translate
. (Mathematicians use the term "translation" for a rigid motion of the plane.) This method moves a rectangle by a certain distance in the x- and y-directions. The method call,
box.translate(15, 25);
moves the rectangle by 15 units in the x-direction and 25 units in the y-direction (see Figure 12). Moving a rectangle doesn't change its width or height, but it changes the top-left corner. Afterward, the rectangle that had its top-left corner at (5, 10) now has it at (20, 35).
This method is a mutator because it modifies the implicit parameter object.
19. Which call to translate
is needed to move the rectangle declared by Rectangle box = new Rectangle(5, 10, 20, 30)
so that its top-left corner is the origin (0, 0)?
The classes and methods of the Java library are listed in the API documentation. The API is the "application programming interface". A programmer who uses the Java classes to put together a computer program (or application) is an application programmer. That's you. In contrast, the programmers who designed and implemented the library classes such as PrintStream
and Rectangle
are system programmers.
You can find the API documentation on the Web. Point your web browser to http://java.sun.com/javase/7/docs/api/index.html
. Appendix D contains an abbreviated version of the API documentation that may be easier to use at first. It is fine if you rely on the abbreviated documentation for your first programs, but you should eventually move on to the real thing.
The API (Application Programming Interface) documentation lists the classes and methods of the Java library.
The API documentation documents all classes in the Java library—there are thousands of them (see Figure 13). Most of the classes are rather specialized, and only a few are of interest to the beginning programmer.
Locate the Rectangle
link in the left pane, preferably by using the search function of your browser. Click on the link, and the right pane shows all the features of the Rectangle
class (see Figure 14).
The API documentation for each class starts out with a section that describes the purpose of the class. Then come summary tables for the constructors and methods (see Figure 15). Click on the link of a method to get a detailed description (see Figure 16).
The detailed description of a method shows
The action that the method carries out.
The parameters that the method receives.
The value that it returns (or the reserved word void
if the method doesn't return any value).
As you can see, the Rectangle
class has quite a few methods. While occasionally intimidating for the beginning programmer, this is a strength of the standard library. If you ever need to do a computation involving rectangles, chances are that there is a method that does all the work for you.
For example, suppose you want to change the width or height of a rectangle. If you browse through the API documentation, you will find a setSize
method with the description "Sets the size of this Rectangle
to the specified width and height." The method has two parameters, described as
width
- the new width for this Rectangle
height
- the new height for this Rectangle
Now let us use this information to change the box
object so that it is a square of side length 40. The name of the method is setSize
, and we supply two parameters: the new width and height:
box.setSize(40, 40);
The API documentation contains another important piece of information about each class. The classes in the standard library are organized into packages. A package is a collection of classes with a related purpose. The Rectangle
class belongs to the package java.awt
(where awt
is an abbreviation for "Abstract Windowing Tool-kit"), which contains many classes for drawing windows and graphical shapes. You can see the package name java.awt
in Figure 14, just above the class name.
To use the Rectangle
class from the java.awt
package, you must import the package. Simply place the following line at the top of your program:
import java.awt.Rectangle;
Why don't you have to import the System
and String
classes? Because the System
and String
classes are in the java.lang
package, and all classes from this package are automatically imported, so you never need to import them yourself.
Java classes are grouped into packages. Use the import
statement to use classes that are declared in other packages.
21. In the API documentation of the String
class, look at the description of the trim
method. What is the result of applying trim
to the string " Hello, Space ! "
? (Note the spaces in the string.)
22. The Random
class is declared in the java.util
package. What do you need to do in order to use that class in your program?
In this section, we discuss the steps that are necessary to implement a test program. The purpose of a test program is to verify that one or more methods have been implemented correctly. A test program calls methods and checks that they return the expected results. Writing test programs is a very important skill.
In this section, we will develop a simple program that tests a method in the Rectangle
class. The program performs the following steps:
Provide a tester class.
Supply a main
method.
Inside the main
method, construct one or more objects.
Apply methods to the objects.
Display the results of the method calls.
Display the values that you expect to get.
Our sample test program tests the behavior of the translate
method. Here are the key steps (which have been placed inside the main
method of the MoveTester
class).
Rectangle box = new Rectangle(5, 10, 20, 30); // Move the rectangle box.translate(15, 25); // Print information about the moved rectangle System.out.print("x: "); System.out.println(box.getX()); System.out.println("Expected: 20");
A test program verifies that methods behave as expected.
We print the value that is returned by the getX
method, and then we print a message that describes the value we expect to see.
This is a very important step. You want to spend some time thinking about the expected result before you run a test program. This thought process will help you understand how your program should behave, and it can help you track down errors at an early stage. Finding and fixing errors early is a very effective strategy that can save you a great deal of time.
Determining the expected result in advance is an important part of testing.
In our case, the rectangle has been constructed with the top-left corner at (5, 10). The x-direction is moved by 15, so we expect an x-value of 5 + 15 = 20 after the move.
Here is a complete program that tests the moving of a rectangle.
ch02/rectangle/MoveTester.java
1
import java.awt.Rectangle;2
3
public class MoveTester4
{5
public static void main(String[] args)6
{7
Rectangle box = new Rectangle(5, 10, 20, 30);8
9
// Move the rectangle10
box.translate(15, 25);11
12
// Print information about the moved rectangle13
System.out.print("x: ");14
System.out.println(box.getX());15
System.out.println("Expected: 20");16
17
System.out.print("y: ");18
System.out.println(box.getY());19
System.out.println("Expected: 35");20
}21
}
x: 20 Expected: 20 y: 35 Expected: 35
24. Why doesn't the MoveTester
program need to print the width and height of the rectangle?
In Java, a variable whose type is a class does not actually hold an object. It merely holds the memory location of an object. The object itself is stored elsewhere—see Figure 17.
There is a reason for this behavior. Objects can be very large. It is more efficient to store only the memory location instead of the entire object.
We use the technical term object reference to denote the memory location of an object. When a variable contains the memory location of an object, we say that it refers to an object. For example, after the statement
Rectangle box = new Rectangle(5, 10, 20, 30);
An object reference describes the location of an object.
the variable box
refers to the Rectangle
object that the new
operator constructed. Technically speaking, the new
operator returned a reference to the new object, and that reference is stored in the box
variable.
It is very important that you remember that the box
variable does not contain the object. It refers to the object. Two object variables can refer to the same object:
Rectangle box2 = box;
Now you can access the same Rectangle
object both as box
and as box2
, as shown in Figure 18.
However, number variables actually store numbers. When you declare
int luckyNumber = 13;
then the luckyNumber
variable holds the number 13, not a reference to the number (see Figure 19). The reason is again efficiency. Because numbers require little storage, it is more efficient to store them directly in a variable.
Multiple object variables can contain references to the same object.
You can see the difference between number variables and object variables when you make a copy of a variable. When you copy a number, the original and the copy of the number are independent values. But when you copy an object reference, both the original and the copy are references to the same object.
Number variables store numbers. Object variables store references.
Consider the following code, which copies a number and then changes the copy (see Figure 20):
int luckyNumber = 13: int luckyNumber2 = luckyNumber; luckyNumber2 = 12;
Now the variable luckyNumber
contains the value 13, and luckyNumber2
contains 12.
Now consider the seemingly analogous code with Rectangle
objects (see Figure 21).
Rectangle box = new Rectangle(5, 10, 20, 30); Rectangle box2 = box; box2.translate(15, 25);
Since box
and box2
refer to the same rectangle after step
You need not worry too much about the difference between objects and object references. Much of the time, you will have the correct intuition when you think of "the object box
" rather than the technically more accurate "the object reference stored in box
". The difference between objects and object references only becomes apparent when you have multiple variables that refer to the same object.
26. After calling greeting2.toUpperCase()
, what are the contents of greeting
and greeting2
?
This is the first of several optional sections that teach you how to write graphical applications: applications that display drawings inside a window. Graphical applications look more attractive than the console applications that show plain text in a console window.
A graphical application shows information inside a frame: a window with a title bar, as shown in Figure 22. In this section, you will learn how to display a frame. In Section 3.9, you will learn how to create a drawing inside the frame.
To show a frame, construct a JFrame
object, set its size, and make it visible.
To show a frame, carry out the following steps:
Construct an object of the JFrame
class:
JFrame frame = new JFrame();
Set the size of the frame:
frame.setSize(300, 400);
This frame will be 300 pixels wide and 400 pixels tall. If you omit this step the frame will be 0 by 0 pixels, and you won't be able to see it. (Pixels are the tiny dots from which digital images are composed.)
If you'd like, set the title of the frame:
frame.setTitle("An Empty Frame");
If you omit this step, the title bar is simply left blank.
Set the "default close operation":
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
When the user closes the frame, the program automatically exits. Don't omit this step. If you do, the program continues running even after the frame is closed.
Make the frame visible:
frame.setVisible(true);
The simple program below shows all of these steps. It produces the empty frame shown in Figure 22.
The JFrame
class is a part of the javax.swing
package. Swing is the nickname for the graphical user interface library in Java. The "x
" in javax
denotes the fact that Swing started out as a Java extension before it was added to the standard library.
We will go into much greater detail about Swing programming in Chapters 3, 9, 10, and 18. For now, consider this program to be the essential plumbing that is required to show a frame.
ch02/emptyframe/EmptyFrameViewer.java
1
import javax.swing.JFrame;2
3
public class EmptyFrameViewer4
{5
public static void main(String[] args)6
{7
JFrame frame = new JFrame();8
9
frame.setSize(300, 400);10
frame.setTitle("An Empty Frame");11
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);12
13
frame.setVisible(true);14
}15
}
28. How can a program display two frames at once?
This section continues the optional graphics track. You will learn how to make shapes appear inside a frame window. The first drawing will be exceedingly modest: just two rectangles (see Figure 23). You'll soon see how to produce more interesting drawings. The purpose of this example is to show you the basic outline of a program that creates a drawing. You cannot draw directly onto a frame. Whenever you want to show anything inside a frame, be it a button or a drawing, you have to construct a component object and add it to the frame. In the Swing toolkit, the JComponent
class represents a blank component.
Since we don't want to add a blank component, we have to modify the JComponent
class and specify how the component should be painted. The solution is to declare a new class that extends the JComponent
class. You will learn about the process of extending classes in Chapter 10. For now, simply use the following code as a template.
In order to display a drawing in a frame, declare a class that extends the JComponent
class.
public class RectangleComponent extends JComponent
{
public void paintComponent(Graphics g)
{
Drawing instructions
}
}
The extends
reserved word indicates that our component class, RectangleComponent
, can be used like a JComponent
. However, the RectangleComponent
class will be different from the plain JComponent
class in one respect: Its paintComponent
method will contain instructions to draw the rectangles.
Place drawing instructions inside the paintComponent
method. That method is called whenever the component needs to be repainted.
When the component is shown for the first time, the paintComponent
method is called automatically. The method is also called when the window is resized, or when it is shown again after it was hidden.
The paintComponent
method receives an object of type Graphics
. The Graphics
object stores the graphics state—the current color, font, and so on, that are used for drawing operations. However, the Graphics
class is primitive. When programmers clamored for a more object-oriented approach for drawing graphics, the designers of Java created the Graphics2D
class, which extends the Graphics
class. Whenever the Swing toolkit calls the paintComponent
method, it actually passes a parameter of type Graphics2D
. Because we want to use the more sophisticated methods to draw two-dimensional graphics objects, we need to use the Graphics2D
class. This is accomplished by using a cast:
public class RectangleComponent extends JComponent { public void paintComponent(Graphics g) { // Recover Graphics2D Graphics2D g2 = (Graphics2D) g; ... } }
Use a cast to recover the Graphics2D
object from the Graphics
parameter of the paintComponent
method.
We cover the concepts of extending classes and of casting in Chapter 10. For now, you should simply include the cast at the top of your paintComponent
methods.
Now you are ready to draw shapes. The draw
method of the Graphics2D
class can draw shapes, such as rectangles, ellipses, line segments, polygons, and arcs. Here we draw a rectangle:
public class RectangleComponent extends JComponent { public void paintComponent(Graphics g) { ... Rectangle box = new Rectangle(5, 10, 20, 30); g2.draw(box); ... } }
Following is the source code for the RectangleComponent
class. Note that the paintComponent
method of the RectangleComponent
class draws two rectangles.
As you can see from the import
statements, the Graphics
and Graphics2D
classes are part of the java.awt
package.
ch02/rectangles/RectangleComponent.java
1
import java.awt.Graphics;2
import java.awt.Graphics2D;3
import java.awt.Rectangle;4
import javax.swing.JComponent;5
6
/*7
A component that draws two rectangles.8
*/9
public class RectangleComponent extends JComponent10
{11
public void paintComponent(Graphics g)12
{13
// Recover Graphics2D14
Graphics2D g2 = (Graphics2D) g;15
16
// Construct a rectangle and draw it17
Rectangle box = new Rectangle(5, 10, 20, 30);18
g2.draw(box);19
20
// Move rectangle 15 units to the right and 25 units down21
box.translate(15, 25);22
23
// Draw moved rectangle24
g2.draw(box);25
}26
}
In order to see the drawing, one task remains. You need to display the frame into which you added a component object. Follow these steps:
Construct a frame as described in the preceding section.
Construct an object of your component class:
RectangleComponent component = new RectangleComponent();
Add the component to the frame:
frame.add(component);
Make the frame visible, as described in the preceding section.
The following listing shows the complete process.
ch02/rectangles/RectangleViewer.java
1
import javax.swing.JFrame;2
3
public class RectangleViewer4
{5
public static void main(String[] args)6
{7
JFrame frame = new JFrame();8
9
frame.setSize(300, 400);10
frame.setTitle("Two rectangles");11
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);12
13
RectangleComponent component = new RectangleComponent();14
frame.add(component);15
16
frame.setVisible(true);17
}18
}
Note that the rectangle drawing program consists of two classes:
The RectangleComponent
class, whose paintComponent
method produces the drawing.
The RectangleViewer
class, whose main
method constructs a frame and a RectangleComponent
, adds the component to the frame, and makes the frame visible.
30. How do you modify the program to draw one rectangle and one square?
31. What happens if you call g.draw(box)
instead of g2.draw(box)
?
In Section 2.12 you learned how to write a program that draws rectangles. In this section you will learn how to draw other shapes: ellipses and lines. With these graphical elements, you can draw quite a few interesting pictures.
To draw an ellipse, you specify its bounding box (see Figure 24) in the same way that you would specify a rectangle, namely by the x- and y-coordinates of the top-left corner and the width and height of the box.
However, there is no simple Ellipse
class that you can use. Instead, you must use one of the two classes Ellipse2D.Float
and Ellipse2D.Double
, depending on whether you want to store the ellipse coordinates as single- or double-precision floating-point values. Because the latter are more convenient to use in Java, we will always use the Ellipse2D.Double
class. Here is how you construct an ellipse:
Ellipse2D.Double ellipse = new Ellipse2D.Double(x, y, width, height);
The Ellipse2D.Double
and Line2D.Double
classes describe graphical shapes.
The class name Ellipse2D.Double
looks different from the class names that you have encountered up to now. It consists of two class names Ellipse2D
and Double
separated by a period (.). This indicates that Ellipse2D.Double
is a so-called inner class inside Ellipse2D
. When constructing and using ellipses, you don't actually need to worry about the fact that Ellipse2D.Double
is an inner class—just think of it as a class with a long name. However, in the import
statement at the top of your program, you must be careful that you import only the outer class:
import java.awt.geom.Ellipse2D;
Drawing an ellipse is easy: Use exactly the same draw
method of the Graphics2D
class that you used for drawing rectangles.
g2.draw(ellipse);
To draw a circle, simply set the width and height to the same values:
Ellipse2D.Double circle = new Ellipse2D.Double(x, y, diameter, diameter); g2.draw(circle);
Notice that (x, y
) is the top-left corner of the bounding box, not the center of the circle.
To draw a line, use an object of the Line2D.Double
class. A line is constructed by specifying its two end points. You can do this in two ways. Simply give the x- and y-coordinates of both end points:
Line2D.Double segment = new Line2D.Double(x1, y1, x2, y2);
Or specify each end point as an object of the Point2D.Double
class:
Point2D.Double from = new Point2D.Double(x1, y1); Point2D.Double to = new Point2D.Double(x2, y2); Line2D.Double segment = new Line2D.Double(from, to);
The second option is more object-oriented and is often more useful, particularly if the point objects can be reused elsewhere in the same drawing.
You often want to put text inside a drawing, for example, to label some of the parts. Use the drawString
method of the Graphics2D
class to draw a string anywhere in a window. You must specify the string and the x- and y-coordinates of the basepoint of the first character in the string (see Figure 25). For example,
g2.drawString("Message", 50, 100);
The drawString
method draws a string, starting at its basepoint.
When you first start drawing, all shapes and strings are drawn with a black pen. To change the color, you need to supply an object of type Color
. Java uses the RGB color model. That is, you specify a color by the amounts of the primary colors—red, green, and blue—that make up the color. The amounts are given as integers between 0 (primary color not present) and 255 (maximum amount present). For example,
Color magenta = new Color(255, 0, 255);
constructs a Color
object with maximum red, no green, and maximum blue, yielding a bright purple color called magenta.
For your convenience, a variety of colors have been declared in the Color
class. Table 4 shows those colors and their RGB values. For example, Color.PINK
has been declared to be the same color as new Color(255, 175, 175)
.
To draw a shape in a different color, first set the color of the Graphics2D
object, then call the draw method:
g2.setColor(Color.RED); g2.draw(circle); // Draws the shape in red
When you set a new color in the graphics context, it is used for subsequent drawing operations.
If you want to color the inside of the shape, use the fill
method instead of the draw
method. For example,
g2.fill(circle);
fills the inside of the circle with the current color.
The following program puts all these shapes to work, creating a simple drawing (see Figure 26).
1
import java.awt.Color;2
import java.awt.Graphics;3
import java.awt.Graphics2D;4
import java.awt.Rectangle;5
import java.awt.geom.Ellipse2D;6
import java.awt.geom.Line2D;7
import javax.swing.JComponent;8
9
/*10
A component that draws an alien face.11
*/12
public class FaceComponent extends JComponent13
{14
public void paintComponent(Graphics g)15
{16
// Recover Graphics2D17
Graphics2D g2 = (Graphics2D) g;18
19
// Draw the head20
Ellipse2D.Double head = new Ellipse2D.Double(5, 10, 100, 150);21
g2.draw(head);22
23
// Draw the eyes24
g2.setColor(Color.GREEN);25
Rectangle eye = new Rectangle(25, 70, 15, 15);26
g2.fill(eye);27
eye.translate(50, 0);28
g2.fill(eye);29
30
// Draw the mouth31
Line2D.Double mouth = new Line2D.Double(30, 110, 80, 110);32
g2.setColor(Color.RED);33
g2.draw(mouth);34
35
// Draw the greeting36
g2.setColor(Color.BLUE);37
g2.drawString("Hello, World!", 5, 175);38
}39
}
1
import javax.swing.JFrame;2
3
public class FaceViewer4
{5
public static void main(String[] args)6
{7
JFrame frame = new JFrame();8
frame.setSize(150, 250);9
frame.setTitle("An Alien Face");10
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);11
12
FaceComponent component = new FaceComponent();13
frame.add(component);14
15
frame.setVisible(true);16
}17
}
33. Give instructions to draw a letter "V" by drawing two line segments.
34. Give instructions to draw a string consisting of the letter "V".
35. What are the RGB color values of Color.BLUE
?
36. How do you draw a yellow square on a red background?
Use integers and floating-point numbers.
A type specifies a set of values and the operations that can be carried out with the values.
The double
type denotes floating-point numbers that can have fractional parts.
In Java, the number types are primitive types, and numbers are not objects.
Numbers can be combined by arithmetic operators such as +, -
, and *
.
Write variable declarations in Java.
You use variables to store values that you want to use at a later time. A variable has a type, a name, and a value.
Identifiers for variables, methods, and classes are composed of letters, digits, and the underscore character.
By convention, variable names should start with a lowercase letter.
Explain the processes of variable assignment and initialization.
Use the assignment operator (=
) to change the value of a variable.
All variables must be initialized before you access them.
Declare objects, classes, and methods.
Objects are entities in your program that you manipulate by calling methods.
A method is a sequence of instructions that accesses the data of an object.
A class declares the methods that you can apply to its objects.
The public interface of a class specifies what you can do with its objects. The hidden implementation describes how these actions are carried out.
Recognize implicit parameters, explicit parameters, and return values of methods.
A parameter is an input to a method.
The implicit parameter of a method call is the object on which the method is invoked. All other parameters are explicit parameters.
The return value of a method is a result that the method has computed for use by the code that called it.
Use constructors to construct new objects.
Use the new
operator, followed by a class name and parameters, to construct new objects.
Classify methods as accessor and mutator methods.
An accessor method does not change the internal data of its implicit parameter. A mutator method changes the data.
Use the API documentation for finding method descriptions and packages.
The API (Application Programming Interface) documentation lists the classes and methods of the Java library.
Java classes are grouped into packages. Use the import
statement to use classes that are declared in other packages.
Write programs that test behavior of methods.
A test program verifies that methods behave as expected.
Determining the expected result in advance is an important part of testing.
Describe how multiple object references can refer to the same object.
An object reference describes the location of an object.
Multiple object variables can contain references to the same object.
Number variables store numbers. Object variables store references.
Write programs that display frame windows.
To show a frame, construct a JFrame
object, set its size, and make it visible.
In order to display a drawing in a frame, declare a class that extends the JComponent
class.
Place drawing instructions inside the paintComponent
method. That method is called whenever the component needs to be repainted.
Use a cast to recover the Graphics2D
object from the Graphics
parameter of the paintComponent
method.
Applets are programs that run inside a web browser.
To run an applet, you need an HTML file with the applet
tag.
You view applets with the applet viewer or a Java-enabled browser.
Use the Java API for drawing simple figures.
The Ellipse2D.Double
and Line2D.Double
classes describe graphical shapes.
The drawString
method draws a string, starting at its basepoint.
When you set a new color in the graphics context, it is used for subsequent drawing operations.
java.awt.Color java.awt.Rectangle java.awt.Component getX getHeight getY getWidth getHeight setSize getWidth setVisible setSize java.awt.Frame translate setTitle java.lang.String java.awt.geom.Ellipse2D.Double length java.awt.geom.Line2D.Double replace java.awt.geom.Point2D.Double toLowerCase java.awt.Graphics toUpperCase setColor javax.swing.JComponent java.awt.Graphics2D paintComponent draw javax.swing.JFrame drawString setDefaultCloseOperation fill
• Worked Example How Many Days Have You Been Alive?
• Worked Example Working with Pictures
• Lab Exercises
R2.1 Explain the difference between an object and an object reference.
R2.2 Explain the difference between an object and an object variable.
R2.3 Explain the difference between an object and a class.
R2.4 Give the Java code for constructing an object of class Rectangle
, and for declaring an object variable of class Rectangle
.
R2.5 Explain the difference between the =
symbol in Java and in mathematics.
R2.6 Give Java code for objects with the following descriptions:
A rectangle with center (100, 100) and all side lengths equal to 50
A string with the contents "Hello, Dave"
Create objects, not object variables.
R2.7 Repeat Exercise R2.6, but now declare object variables that are initialized with the required objects.
R2.8 Write a Java statement to initialize a variable square
with a rectangle object whose top left corner is (10, 20) and whose sides all have length 40. Then write a statement that replaces square
with a rectangle of the same size and top left corner (20, 20).
R2.9 Write Java statements that initialize two variables square1
and square2
to refer to the same square with center (20, 20) and side length 40.
R2.10 Write Java statements that initialize a string message
with "Hello"
and then change it to "HELLO"
. Use the toUpperCase
method.
R2.11 Write Java statements that initialize a string message
with "Hello"
and then change it to "hello"
. Use the replace
method.
R2.12 Find the errors in the following statements:
Rectangle r = (5, 10, 15, 20);
double width = Rectangle(5, 10, 15, 20).getWidth();
Rectangle r;
r.translate(15, 25);
r = new Rectangle();
r.translate("far, far away!");
R2.13 Name two accessor methods and two mutator methods of the Rectangle
class.
R2.14 Look into the API documentation of the Rectangle
class and locate the method
void add(int newx, int newy)
Read through the method documentation. Then determine the result of the following statements:
Rectangle box = new Rectangle(5, 10, 20, 30); box.add(0, 0);
If you are not sure, write a small test program.
R2.15 What is the difference between a console application and a graphical application?
R2.16 Who calls the paintComponent
method of a component? When does the call to the paintComponent
method occur?
R2.17 Why does the parameter of the paintComponent
method have type Graphics
and not Graphics2D
?
R2.18 What is the purpose of a graphics context?
R2.19 Why are separate viewer and component classes used for graphical programs?
R2.20 How do you specify a text color?
P2.1 Write an AreaTester
program that constructs a Rectangle
object and then computes and prints its area. Use the getWidth
and getHeight
methods. Also print the expected answer.
P2.2 Write a PerimeterTester
program that constructs a Rectangle
object and then computes and prints its perimeter. Use the getWidth
and getHeight
methods. Also print the expected answer.
P2.3 Write a program called FourRectanglePrinter
that constructs a Rectangle
object, prints its location by calling System.out.println(box)
, and then translates and prints it three more times, so that, if the rectangles were drawn, they would form one large rectangle:
Your program will not produce a drawing. It will simply print the locations of the four rectangles.
P2.4 Write a GrowSquarePrinter
program that constructs a Rectangle
object square
representing a square with top-left corner (100, 100) and side length 50, prints its location by calling System.out.println(square)
, applies the translate
and grow
methods and calls System.out.println(square)
again. The calls to translate
and grow
should modify the square so that it has twice the size and the same top-left corner as the original. If the squares were drawn, they would look like this:
Your program will not produce a drawing. It will simply print the locations of square before and after calling the mutator methods.
Look up the description of the grow
method in the API documentation.
P2.5 The intersection
method computes the intersection of two rectangles—that is, the rectangle that would be formed by two overlapping rectangles if they were drawn:
You call this method as follows:
Rectangle r3 = r1.intersection(r2);
Write a program IntersectionPrinter
that constructs two rectangle objects, prints them as described in Exercise P2.3, and then prints the rectangle object that describes the intersection. Then the program should print the result of the intersection
method when the rectangles do not overlap. Add a comment to your program that explains how you can tell whether the resulting rectangle is empty.
P2.6 In this exercise, you will explore a simple way of visualizing a Rectangle
object. The setBounds
method of the JFrame
class moves a frame window to a given rectangle. Complete the following program to visually show the translate
method of the Rectangle
class:
import java.awt.Rectangle; import javax.swing.JFrame; import javax.swing.JOptionPane; public class TranslateDemo { public static void main(String[] args) { // Construct a frame and show it JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); // Your work goes here: // Construct a rectangle and set the frame bounds JOptionPane.showMessageDialog(frame, "Click OK to continue"); // Your work goes here: // Move the rectangle and set the frame bounds again } }
P2.7 In the Java library, a color is specified by its red, green, and blue components between 0 and 255 (see Table 4 on page 67). Write a program BrighterDemo
that constructs a Color
object with red, green, and blue values of 50, 100, and 150. Then apply the brighter
method and print the red, green, and blue values of the resulting color. (You won't actually see the color—see the next exercise on how to display the color.)
P2.8 Repeat Exercise P2.7, but place your code into the following class. Then the color will be displayed.
import java.awt.Color; import javax.swing.JFrame; public class BrighterDemo { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setSize(200, 200); Color myColor = ...; frame.getContentPane().setBackground(myColor); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
P2.9 Repeat Exercise P2.7, but apply the darker
method twice to the object Color.RED
. Call your class DarkerDemo
.
P2.10 The Random
class implements a random number generator, which produces sequences of numbers that appear to be random. To generate random integers, you construct an object of the Random
class, and then apply the nextInt
method. For example, the call generator.nextInt(6)
gives you a random number between 0 and 5.
Write a program DieSimulator
that uses the Random
class to simulate the cast of a die, printing a random number between 1 and 6 every time that the program is run.
P2.11 Write a program LotteryPrinter
that picks a combination in a lottery. In this lottery, players can choose 6 numbers (possibly repeated) between 1 and 49. (In a real lottery, repetitions aren't allowed, but we haven't yet discussed the programming constructs that would be required to deal with that problem.) Your program should print out a sentence such as "Play this combination—it'll make you rich!", followed by a lottery combination.
P2.12 Write a program ReplaceTester
that encodes a string by replacing all letters "i"
with "!"
and all letters "s"
with "$"
. Use the replace
method. Demonstrate that you can correctly encode the string "Mississippi"
. Print both the actual and expected result.
P2.13 Write a program HollePrinter
that switches the letters "e"
and "o"
in a string. Use the replace
method repeatedly. Demonstrate that the string "Hello, World!"
turns into "Holle, Werld!"
P2.14 Write a graphics program that draws your name in red, contained inside a blue rectangle. Provide a class NameViewer
and a class NameComponent
.
P2.15 Write a graphics program that draws 12 strings, one each for the 12 standard colors, besides Color.WHITE
, each in its own color. Provide a class ColorNameViewer
and a class ColorNameComponent
.
P2.16 Write a program that draws two solid squares: one in pink and one in purple. Use a standard color for one of them and a custom color for the other. Provide a class TwoSquareViewer
and a class TwoSquareComponent
.
P2.17 Write a program that fills the window with a large ellipse, with a black outline and filled with your favorite color. The ellipse should touch the window boundaries, even if the window is resized.
P2.18 Write a program to plot the following face.
Provide a class FaceViewer
and a class FaceComponent
.
Project 2.1 The GregorianCalendar
class describes a point in time, as measured by the Gregorian calendar, the standard calendar that is commonly used throughout the world today. You construct a GregorianCalendar
object from a year, month, and day of the month, like this:
GregorianCalendar cal = new GregorianCalendar(); // Today's date GregorianCalendar eckertsBirthday = new GregorianCalendar(1919, Calendar.APRIL, 9);
Use the values Calendar.JANUARY . . . Calendar.DECEMBER
to specify the month.
The add
method can be used to add a number of days to a GregorianCalendar
object:
cal.add(Calendar.DAY_OF_MONTH, 10); // Now cal is ten days from today
This is a mutator method—it changes the cal
object.
The get
method can be used to query a given GregorianCalendar
object:
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH); int month = cal.get(Calendar.MONTH); int year = cal.get(Calendar.YEAR); int weekday = cal.get(Calendar.DAY_OF_WEEK); // 1 is Sunday, 2 is Monday, ..., 7 is Saturday
Your task is to write a program that prints the following information:
The date and weekday that is 100 days from today
The weekday of your birthday
The date that is 10,000 days from your birthday
Use the birthday of a computer scientist if you don't want to reveal your own birthday.
Project 2.2 Run the following program:
import java.awt.Color; import javax.swing.JFrame; import javax.swing.JLabel; public class FrameViewer { public static void main(String[] args) {
JFrame frame = new JFrame(); frame.setSize(200, 200); JLabel label = new JLabel("Hello, World!"); label.setOpaque(true); label.setBackground(Color.PINK); frame.add(label); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
Modify the program as follows:
Double the frame size.
Change the greeting to "Hello, your name!".
Change the background color to pale green (see Exercise P2.7).
For extra credit, add an image of yourself. (Hint: Construct an ImageIcon
.)
int
and String
double
An int
is not an object, and you cannot call a method on it.
(x + y) * 0.5
Only the first two are legal identifiers.
String myName = "John Q. Public";
No, the left-hand side of the =
operator must be a variable.
greeting = "Hello, Nina!";
Note that
String greeting = "Hello, Nina!";
is not the right answer—that statement declares a new variable.
river.length()
or "Mississippi".length()
System.out.println(greeting.toUpperCase());
or
System.out.println("Hello, World!".toUpperCase());
It is not legal. The variable river
has type String
. The println
method is not a method of the String
class.
The implicit parameter is river
. There is no explicit parameter. The return value is 11.
"Missississi"
12
As public String toUpperCase()
, with no explicit parameter and return type String
.
new Rectangle(90, 90, 20, 20)
0
An accessor—it doesn't modify the original string but returns a new string with uppercase letters.
box.translate(−5, −10)
, provided the method is called immediately after storing the new rectangle into box
.
toLowerCase
"Hello, Space !"
—only the leading and trailing spaces are trimmed.
Add the statement import java.util.Random;
at the top of your program.
x: 30, y: 25
Because the translate
method doesn't modify the shape of the rectangle.
Now greeting
and greeting2
both refer to the same String
object.
Both variables still refer to the same string, and the string has not been modified. Recall that the toUpperCase
method constructs a new string that contains uppercase characters, leaving the original string unchanged.
Modify the EmptyFrameViewer
program as follows:
frame.setSize(300, 300); frame.setTitle("Hello, World!");
Construct two JFrame
objects, set each of their sizes, and call setVisible(true)
on each of them.
Rectangle box = new Rectangle(5, 10, 20, 20);
Replace the call to box.translate(15, 25)
with
box = new Rectangle(20, 35, 20, 20);
The compiler complains that g
doesn't have a draw
method.
g2.draw(new Ellipse2D.Double(75, 75, 50, 50));
Line2D.Double segment1 = new Line2D.Double(0, 0, 10, 30); g2.draw(segment1); Line2D.Double segment2 = new Line2D.Double(10, 30, 20, 0); g2.draw(segment2);
g2.drawString("V", 0, 30);
0, 0, 255
First fill a big red square, then fill a small yellow square inside:
g2.setColor(Color.RED); g2.fill(new Rectangle(0, 0, 200, 200)); g2.setColor(Color.YELLOW); g2.fill(new Rectangle(50, 50, 100, 100));
3.143.205.27