Chapter 9

Constructing New Objects

In This Chapter

arrow Defining constructors

arrow Using constructors in subclasses

arrow Using Java’s default constructor features

arrow Constructing a simple GUI

Ms. Jennie Burd
121 Schoolhouse Lane
Anywhere, Kansas

Dear Ms. Burd,

In response to your letter of June 21, I believe I can say with complete assurance that objects are not created spontaneously from nothing. Although I’ve never actually seen an object being created (and no one else in this office can claim to have seen an object in its moment of creation), I have every confidence that some process or other is responsible for the building of these interesting and useful thingamajigs. We here at ClassesAndObjects.com support the unanimous opinions of both the scientific community and the private sector on matters of this nature. Furthermore, we agree with the recent finding of a Blue Ribbon Presidential Panel, which concludes beyond any doubt that spontaneous object creation would impede the present economic outlook.

Please be assured that I have taken all steps necessary to ensure the safety and well-being of you, our loyal customer. If you have any further questions, please do not hesitate to contact our complaint department. The department’s manager is Mr. Blake Wholl. You can contact him by visiting our company’s website.

Once again, let me thank you for your concern, and I hope you continue to patronize ClassesAndObjects.com.

Yours truly,

Mr. Scott Brickenchicker

The one who couldn’t get on the elevator in Chapter 4

Defining Constructors (What It Means to Be a Temperature)

Here’s a statement that creates an object:

  Account myAccount = new Account();

I know this works — I got it from one of my own examples in Chapter 7. Anyway, in Chapter 7, I say, “when the computer executes new Account(), you’re creating an object by calling the Account class’s constructor.” What does this mean?

Well, when you ask the computer to create a new object, the computer responds by performing certain actions. For starters, the computer finds a place in its memory to store information about the new object. If the object has fields, the fields should eventually have meaningful values.

cross-reference.eps To find out about fields, see Chapter 7.

So one question is, when you ask the computer to create a new object, can you control what’s placed in the object’s fields? And what if you’re interested in doing more than filling fields? Perhaps, when the computer creates a new object, you have a whole list of jobs for the computer to carry out. For instance, when the computer creates a new window object, you want the computer to realign the sizes of all the buttons in that window.

Creating a new object can involve all kinds of tasks, so in this chapter, you create constructors. A constructor tells the computer to perform a new object’s startup tasks.

What is a temperature?

“Good morning, and welcome to Object News. The local temperature in your area is a pleasant 73 degrees Fahrenheit.”

Each temperature consists of two things: a number and a temperature scale. A number is just a double value, such as 32.0 or 70.52. But what's a temperature scale? Is it a string of characters, like "Fahrenheit" or "Celsius"? Not really, because some strings aren't temperature scales. There's no "Quelploof" temperature scale, and a program that can display the temperature “73 degrees Quelploof” is a bad program. So how can you limit the temperature scales to the small number of scales that people use? One way to do it is with Java's enum type.

What is a temperature scale? (Java's enum type)

Java provides lots of ways for you to group things together. In Chapter 11, you group things together to form an array. And in Chapter 12, you group things together to form a collection. In this chapter, you group things into an enum type. (Of course, you can’t group anything unless you can pronounce enum. The word enum is pronounced ee-noom, like the first two syllables of the word enumeration.)

Creating a complicated enum type isn’t easy, but to create a simple enum type, just write a bunch of words inside a pair of curly braces. Listing 9-1 defines an enum type. The name of the enum type is TempScale.

Listing 9-1: The TempScale enum Type

  public enum TempScale {
   CELSIUS, FAHRENHEIT, KELVIN, RANKINE,
   NEWTON, DELISLE, RÉAUMUR, RØMER, LEIDEN
};                

When you define an enum type, two important things happen:

  • You create values.

    Just as 13 and 151 are int values, CELSIUS and FAHRENHEIT are TempScale values.

  • You can create variables to refer to those values.

    In Listing 9-2, I declare the fields number and scale. Just as double number declares a number variable is of type double, TempScale scale declares variable scale to be of type TempScale.

    Being of type TempScale means that you can have values CELSIUS, FAHRENHEIT, KELVIN, and so on. So in Listing 9-2, I can give the scale variable the value FAHRENHEIT (or TempScale.FAHRENHEIT, to be more precise).

technicalstuff.eps An enum type is a Java class in disguise. That's why Listing 9-1 contains an entire file devoted to one thing; namely, the declaration of the TempScaleenum type. Like the declaration of a class, an enum type declaration belongs in a file all its own. The code in Listing 9-1 belongs in a file named TempScale.java.

Okay, so then what is a temperature?

Each temperature consists of two things: a number and a temperature scale. The code in Listing 9-2 makes this fact abundantly clear.

Listing 9-2: The Temperature Class

  public class Temperature {
   private double number;

   private TempScale scale;

   public Temperature() {
      number = 0.0;
      scale = TempScale.FAHRENHEIT;
   }

   public Temperature(double number) {
      this.number = number;
      scale = TempScale.FAHRENHEIT;
   }

   public Temperature(TempScale scale) {
      number = 0.0;
      this.scale = scale;
   }

   public Temperature(double number, TempScale scale) {
      this.number = number;
      this.scale = scale;
   }

   public void setNumber(double number) {
      this.number = number;
   }

   public double getNumber() {
      return number;
   }

   public void setScale(TempScale scale) {
      this.scale = scale;
   }

   public TempScale getScale() {
      return scale;
   }
}

The code in Listing 9-2 has the usual setter and getter methods (accessor methods for the number and scale fields).

cross-reference.eps For some good reading on setter and getter methods (also known as accessor methods), see Chapter 7.

On top of all that, Listing 9-2 has four other method-like looking things. Each of these method-like things has the name Temperature, which happens to be the same as the name of the class. None of these Temperature method-like things has a return type of any kind — not even void, which is the cop-out return type.

Each of these method-like things is called a constructor. A constructor is like a method, except that a constructor has a very special purpose — creating new objects.

remember.eps Whenever the computer creates a new object, the computer executes the statements inside a constructor.

You can omit the word public in the first lines of Listings 2-9 and 1-4. If you omit public, other Java programs might not be able to use the features defined in your TempScaleenum and in your Temperature class. (Don't worry about the programs in this chapter. With or without the word public, all the programs in this chapter can use the code in Listings 2-9 and 1-4. To find out which Java programs can and cannot use non-public classes, see Chapter 14.) If you do use the word public in the first line of Listing 9-1, Listing 9-1 must be in a file named TempScale.java, starting with a capital letter T. And if you do use the word public in the first line of Listing 9-2, Listing 9-2 must be in a file named Temperature.java, starting with a capital letter T. (For an introduction to public classes, see Chapter 7.)

What you can do with a temperature

Listing 9-3 gives form to some of the ideas that I describe in the preceding section. In Listing 9-3, you call the constructors that are declared back in Listing 9-2. Figure 9-1 shows what happens when you run all this code.

9781118407806-fg0901.tif

Figure 9-1: Running the code from Listing 9-3.

Listing 9-3: Using the Temperature Class

  import static java.lang.System.out;

public class UseTemperature {

  public static void main(String args[]) {
     final String format = "%5.2f degrees %s ";

     Temperature temp = new Temperature();
     temp.setNumber(70.0);
     temp.setScale(TempScale.FAHRENHEIT);
     out.printf(format, temp.getNumber(),
                    temp.getScale());

     temp = new Temperature(32.0);
     out.printf(format, temp.getNumber(),
                    temp.getScale());

     temp = new Temperature(TempScale.CELSIUS);
     out.printf(format, temp.getNumber(),
                    temp.getScale());

     temp = new Temperature(2.73, TempScale.KELVIN);
     out.printf(format, temp.getNumber(),
                    temp.getScale());
  }
}

remember.eps The examples in the printed book are mostly text-based, but you can find fancier versions of most examples on this book's website (www.allmycode.com/JavaForDummies). These fancier versions have windows, buttons, text fields, and other elements of a typical graphical user interface (GUI).

In Listing 9-3, each statement of the kind

  temp = new Temperature(blah,blah,blah);

calls one of the constructors from Listing 9-2. So, by the time the code in Listing 9-3 is done running, it creates four instances of the Temperature class. Each instance is created by calling a different constructor from Listing 9-2.

In Listing 9-3, the last of the four constructor calls has two parameters — 2.73 and TempScale.KELVIN. This isn't particular to constructor calls. A method call or a constructor call can have a bunch of parameters. You separate one parameter from another with a comma. Another name for “a bunch of parameters” is a parameter list.

The only rule you must follow is to match the parameters in the call with the parameters in the declaration. For example, in Listing 9-3, the fourth and last constructor call

  new Temperature(2.73, TempScale.KELVIN)

has two parameters — the first of type double, and the second of type TempScale. Java approves of this constructor call because Listing 9-2 contains a matching declaration. That is, the header

  public Temperature(double number, TempScale scale)

has two parameters — the first of type double, and the second of type TempScale. If a Temperature constructor call in Listing 9-3 had no matching declaration in Listing 9-2, then Listing 9-3 would crash and burn. (To state things more politely, Java would display errors when you tried to compile the code in Listing 9-3.)

By the way, this business about multiple parameters isn't new. Back in Chapter 6, I write keyboard.findWithinHorizon(".",0).charAt(0). In that line, the method call findWithinHorizon(".",0) has two parameters — a string and an int value. Lucky for me, the Java API has a method declaration for findWithinHorizon — a declaration whose first parameter is a string, and whose second parameter is an int value.

Calling new Temperature(32.0): A case study

When the computer executes one of the new Temperature statements in Listing 9-3, the computer has to decide which of the constructors in Listing 9-2 to use. The computer decides by looking at the parameter list — the stuff in parentheses after the words new Temperature. For instance, when the computer executes

  temp = new Temperature(32.0);

from Listing 9-3, the computer says to itself, “The number 32.0 in parentheses is a double value. One of the Temperature constructors in Listing 9-2 has just one parameter with type double. The constructor’s header looks like this:

  public Temperature(double number)

“So, I guess I’ll execute the statements inside that particular constructor.” The computer goes on to execute the following statements:

  this.number = number;
scale = TempScale.FAHRENHEIT;

As a result, you get a brand-new object whose number field has the value 32.0 and whose scale field has the value TempScale.FAHRENHEIT.

In the two lines of code, you have two statements that set values for the fields number and scale. Take a look at the second of these statements, which is a bit easier to understand. The second statement sets the new object’s scale field to TempScale.FAHRENHEIT. You see, the constructor’s parameter list is (double number), and that list doesn’t include a scale value. So whoever programmed this code had to make a decision about what value to use for the scale field. The programmer could have chosen FAHRENHEIT or CELSIUS, but she could also have chosen KELVIN, RANKINE, or any of the other obscure scales named in Listing 9-1. (This programmer happens to live in New Jersey, in the United States, where people commonly use the old Fahrenheit temperature scale.)

Marching back to the first of the two statements, this first statement assigns a value to the new object’s number field. The statement uses a cute trick that you can see in many constructors (and in other methods that assign values to objects’ fields). To understand the trick, take a look at Listing 9-4. The listing shows you two ways that I could have written the same constructor code.

Listing 9-4: Two Ways to Accomplish the Same Thing

  //Use this constructor …

     public Temperature(double whatever) {
        number = whatever;
        scale = TempScale.FAHRENHEIT;
     }

//… or use this constructor …

     public Temperature(double number) {
        this.number = number;
        scale = TempScale.FAHRENHEIT;
     }

//… but don't put both constructors in your code.

Listing 9-4 has two constructors in it. In the first constructor, I use two different names — number and whatever. In the second constructor, I don’t need two names. Instead of making up a new name for the constructor’s parameter, I reuse an existing name by writing this.number.

So here’s what’s going on in Listing 9-2:

  • In the statement this.number = number, the name this.number refers to the new object’s number field — the field that’s declared near the very top of Listing 9-2. (See Figure 9-2.)

    In the statement this.number = number, number (on its own, without this) refers to the constructor’s parameter. (Again, see Figure 9-2.)

    9781118407806-fg0902.tif

    Figure 9-2: What this.number and number mean.

In general, this.someName refers to a field belonging to the object that contains the code. In contrast, plain old someName refers to the closest place where someName happens to be declared. In the statement this.number = number (Listing 9-2), that closest place happens to be the Temperature constructor’s parameter list.

Some things never change

Chapter 7 introduces the printf method and explains that each printf call starts with a format string. The format string describes the way the other parameters are to be displayed.

In previous examples, this format string is always a quoted literal. For instance, the first printf call in Listing 7-7 is

  out.printf("$%4.2f ", myInterest);

In Listing 9-3, I break with tradition and begin the printf call with a variable that I name format.

  out.printf(format, temp.getNumber(), temp.getScale());

That’s okay as long as my format variable is of type String. And indeed, in Listing 9-3, the first variable declaration is

  final String format = "%5.2f degrees %s ";

In this declaration of the format variable, take special note of the word final. This Java keyword indicates that the value of format can’t be changed. If I add another assignment statement to Listing 9-3

  format = "%6.2f (%s) ";

then the compiler barks back at me with a cannot assign a value to final variable message.

When I write the code in Listing 9-3, the use of the final keyword isn’t absolutely necessary. But the final keyword provides some extra protection. When I initialize format to "%5.2f degrees %s ", I intend to use this same format just as it is, over and over again. I know darn well that I don’t intend to change the format variable’s value. Of course, in a 10,000-line program, I can become confused and try to assign a new value to format somewhere deep down in the code. So to prevent me from accidentally changing the format string, I declare the format variable to be final. It’s just good, safe programming practice.

More Subclasses (Doing Something about the Weather)

In Chapter 8, I make a big fuss over the notion of subclasses. That’s the right thing to do. Subclasses make code reusable, and reusable code is good code. With that in mind, it’s time to create a subclass of the Temperature class (which I develop in this chapter’s first section).

Building better temperatures

After perusing the code in Listing 9-3, you decide that the responsibility for displaying temperatures has been seriously misplaced. Listing 9-3 has several tedious repetitions of the lines to print temperature values. A 1970s programmer would tell you to collect those lines into one place and turn them into a method. (The 1970s programmer wouldn’t have used the word method, but that’s not important right now.) Collecting lines into methods is fine, but with today’s object-oriented programming methodology, you think in broader terms. Why not get each temperature object to take responsibility for displaying itself? After all, if you develop a display method, you probably want to share the method with other people who use temperatures. So put the method right inside the declaration of a temperature object. That way, anyone who uses the code for temperatures has easy access to your display method.

Now replay the tape from Chapter 8. “Blah, blah, blah … don’t want to modify existing code … blah, blah, blah … too costly to start again from scratch … blah, blah, blah … extend existing functionality.” It all adds up to one thing:

Don’t abuse it. Instead, reuse it.

So you decide to create a subclass of the Temperature class — the class defined in Listing 9-2. Your new subclass complements the Temperature class’s functionality by having methods to display values in a nice, uniform fashion. The new class, TemperatureNice, is shown in Listing 9-5.

Listing 9-5: The TemperatureNice Class

  import static java.lang.System.out;

public class TemperatureNice extends Temperature {

   public TemperatureNice() {
         super();
   }

   public TemperatureNice(double number) {
         super(number);
   }

   public TemperatureNice(TempScale scale) {
         super(scale);
   }

   public TemperatureNice(double number, TempScale scale)
   {
         super(number, scale);
   }

   public void display() {
      out.printf("%5.2f degrees %s ",
                       getNumber(), getScale());
   }
}

In the display method of Listing 9-5, notice the calls to the Temperature class’s getNumber and getScale methods. Why do I do this? Well, inside the TemperatureNice class’s code, any direct references to the number and scale fields would generate error messages. It’s true that every TemperatureNice object has its own number and scale fields. (After all, TemperatureNice is a subclass of the Temperature class, and the code for the Temperature class defines the number and scale fields.) But because number and scale are declared to be private inside the Temperature class, only code that’s right inside the Temperature class can directly use these fields.

warning.eps Don’t put additional declarations of the number and scale fields inside the TemperatureNice class’s code. If you do, you inadvertently create four different variables (two called number, and another two called scale). You’ll assign values to one pair of variables. Then you’ll be shocked that, when you display the other pair of variables, those values seem to have disappeared.

remember.eps When an object’s code contains a call to one of the object’s own methods, you don’t need to preface the call with a dot. For instance, in the last statement of Listing 9-5, the object calls its own methods with getNumber() and getScale(), not with someObject.getNumber() and somethingOrOther.getScale(). If going dotless makes you queasy, you can compensate by taking advantage of yet another use for the this keyword. Just write this.getNumber() and this.getScale() in the last line of Listing 9-5.

Constructors for subclasses

By far, the biggest news in Listing 9-5 is the way the code declares constructors. The TemperatureNice class has four of its own constructors. If you’ve gotten in gear thinking about subclass inheritance, you may wonder why these constructor declarations are necessary. Doesn’t TemperatureNice inherit the parent Temperature class’s constructors? No, subclasses don’t inherit constructors.

remember.eps Subclasses don’t inherit constructors.

That’s right. Subclasses don’t inherit constructors. In one oddball case, a constructor may look like it’s being inherited, but that oddball situation is a fluke, not the norm. In general, when you define a subclass, you declare new constructors to go with the subclass.

I describe the oddball case (in which a constructor looks like it’s being inherited) later in this chapter, in the section “The default constructor.”

So the code in Listing 9-5 has four constructors. Each constructor has the name TemperatureNice, and each constructor has its own uniquely identifiable parameter list. That’s the boring part. The interesting part is that each constructor makes a call to something named super, which is a Java keyword.

In Listing 9-5, super stands for a constructor in the parent class.

  • The statement super() in Listing 9-5 calls the parameterless Temperature() constructor that’s in Listing 9-2. That parameterless constructor assigns 0.0 to the number field and TempScale.FAHRENHEIT to the scale field.
  • The statement super(number, scale) in Listing 9-5 calls the constructor Temperature(double number, TempScale scale) that’s in Listing 9-2. In turn, the constructor assigns values to the number and scale fields.
  • In a similar way, the statements super(number) and super(scale) in Listing 9-5 call constructors from Listing 9-2.

The computer decides which of the Temperature class’s constructors is being called by looking at the parameter list after the word super. For instance, when the computer executes

  super(number, scale);

from Listing 9-5, the computer says to itself, “The number and scale fields in parentheses have types double and TempScale. But only one of the Temperature constructors in Listing 9-2 has two parameters with types double and TempScale. The constructor’s header looks like this:

  public Temperature(double number, TempScale scale)

“So, I guess I’ll execute the statements inside that particular constructor.”

Using all this stuff

In Listing 9-5, I define what it means to be in the TemperatureNice class. Now it’s time to put this TemperatureNice class to good use. Listing 9-6 has code that uses TemperatureNice.

Listing 9-6: Using the TemperatureNice Class

  public class UseTemperatureNice {

   public static void main(String args[]) {

            TemperatureNice temp = new TemperatureNice();
      temp.setNumber(70.0);
      temp.setScale(TempScale.FAHRENHEIT);
      temp.display();

      temp = new TemperatureNice(32.0);
      temp.display();

      temp = new TemperatureNice(TempScale.CELSIUS);
      temp.display();

      temp = new TemperatureNice(2.73,
                          TempScale.KELVIN);
      temp.display();
   }
}

The code in Listing 9-6 is very much like its cousin code in Listing 9-3. The big differences are as follows:

  • Listing 9-6 creates instances of the TemperatureNice class. That is, Listing 9-6 calls constructors from the TemperatureNice class, not the Temperature class.
  • Listing 9-6 takes advantage of the display method in the TemperatureNice class. So the code in Listing 9-6 is much tidier than its counterpart in Listing 9-3.

A run of Listing 9-6 looks exactly like a run of the code in Listing 9-3 — it just gets to the finish line in far more elegant fashion. (The run is shown previously in Figure 9-1.)

The default constructor

The main message in the previous section is that subclasses don’t inherit constructors. So what gives with all the listings back in Chapter 8? In Listing 8-6, a statement says

  FullTimeEmployee ftEmployee = new FullTimeEmployee();

But, here’s the problem: The code defining FullTimeEmployee (Listing 8-3) doesn’t seem to have any constructors declared inside it. So, in Listing 8-6, how can you possibly call the FullTimeEmployee constructor?

Here’s what’s going on. When you create a subclass and don’t put any explicit constructor declarations in your code, Java creates one constructor for you. It’s called a default constructor. If you’re creating the public FullTimeEmployee subclass, the default constructor looks like the one in Listing 9-7.

Listing 9-7: A Default Constructor

  public FullTimeEmployee() {
   super();
}

The constructor in Listing 9-7 takes no parameters, and its one statement calls the constructor of whatever class you’re extending. (Woe be to you if the class that you’re extending doesn’t have a parameterless constructor.)

You’ve just read about default constructors, but watch out! Notice one thing that this talk about default constructors doesn’t say: It doesn’t say that you always get a default constructor. In particular, if you create a subclass and define any constructors yourself, Java doesn’t add a default constructor for the subclass (and the subclass doesn’t inherit any constructors, either).

So how can this trip you up? Listing 9-8 has a copy of the code from Listing 8-3, but with one constructor added to it. Take a look at this modified version of the FullTimeEmployee code.

Listing 9-8: Look, I Have a Constructor!

  public class FullTimeEmployee extends Employee {
   private double weeklySalary;
   private double benefitDeduction;

   public FullTimeEmployee(double weeklySalary) {
      this.weeklySalary = weeklySalary;
   }

   public void setWeeklySalary(double weeklySalaryIn) {
      weeklySalary = weeklySalaryIn;
   }

   public double getWeeklySalary() {
      return weeklySalary;
   }

   public void setBenefitDeduction(double benefitDedIn) {
      benefitDeduction = benefitDedIn;
   }

   public double getBenefitDeduction() {
      return benefitDeduction;
   }

   public double findPaymentAmount() {
      return weeklySalary - benefitDeduction;
   }
}

If you use the FullTimeEmployee code in Listing 9-8, a line like the following doesn’t work:

  FullTimeEmployee ftEmployee = new FullTimeEmployee();

It doesn’t work because, having declared a FullTimeEmployee constructor that takes one double parameter, you no longer get a default parameterless constructor for free.

So what do you do about this? If you declare any constructors, declare all the constructors that you’re possibly going to need. Take the constructor in Listing 9-7 and add it to the code in Listing 9-8. Then the call new FullTimeEmployee() starts working again.

ontheweb_fmt.eps Under certain circumstances, Java automatically adds an invisible call to a parent class's constructor at the top of a constructor body. This automatic addition of a super call is a tricky bit of business that doesn’t appear often, so when it does appear, it may seem quite mysterious. For more information, see this book's website (www.allmycode.com/JavaForDummies).

A Constructor That Does More

Here’s a quote from someplace near the start of this chapter: “And what if you’re interested in doing more than filling fields? Perhaps, when the computer creates a new object, you have a whole list of jobs for the computer to carry out.” Okay, what if?

This section’s example has a constructor that does more than just assign values to fields. The example is in Listings 2-9 and 9-4. The result of running the example’s code is shown in Figure 9-3.

Listing 9-9: Defining a Frame

  import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JButton;

@SuppressWarnings("serial")
public class SimpleFrame extends JFrame {

   public SimpleFrame() {
      setTitle("Don't click the button!");
      setLayout(new FlowLayout());
      setDefaultCloseOperation(EXIT_ON_CLOSE);
      add(new JButton("Panic"));
      setSize(300, 100);
      setVisible(true);
   }
}

Listing 9-10: Displaying a Frame

  public class ShowAFrame {

   public static void main(String args[]) {
      new SimpleFrame();
   }
}

9781118407806-fg0903.tif

Figure 9-3: Don’t panic.

The code in Listing 9-9 is made up mostly of calls to Java API (Application Programming Interface) methods. What this means to you is that the code contains lots of names that are probably unfamiliar to you. When I was first becoming acquainted with Java, I foolishly believed that knowing Java meant knowing all these names. Quite the contrary: These names are just carry-on baggage. The real Java is the way the language implements object-oriented concepts.

Anyway, Listing 9-10’s main method has only one statement: a call to the constructor in the SimpleFrame class. Notice how the object that this call creates isn’t even assigned to a variable. That’s okay because the code doesn’t need to refer to the object anywhere else.

Up in the SimpleFrame class is only one constructor declaration. Far from just setting variables’ values, this constructor calls method after method from the Java API.

All the methods called in the SimpleFrame class’s constructor come from the parent class, JFrame. The JFrame class lives in the javax.swing package. This package and another package, java.awt, have classes that help you put windows, images, drawings, and other gizmos on a computer screen. (In the java.awt package, the letters awt stand for abstract windowing toolkit.)

For a little gossip about the notion of a Java package, see the sidebar entitled “Packages and import declarations.” For lots of gossip about the notion of a Java package, see Chapter 14.

remember.eps In the Java API, what people normally call a window is an instance of the javax.swing.JFrame class.

Classes and methods from the Java API

Looking at Figure 9-3, you can probably tell that an instance of the Simple​Frame class doesn’t do much. The frame has only one button, and when you click the button, nothing happens. I made the frame this way to keep the example from becoming too complicated. Even so, the code in Listing 9-9 uses several API classes and methods. The setTitle, setLayout, setDefaultCloseOperation, add, setSize, and setVisible methods all belong to the javax.swing.JFrame class. Here’s a list of names used in the code:

  • setTitle: Calling setTitle puts words in the frame’s title bar. (The new SimpleFrame object is calling its own setTitle method.)
  • FlowLayout: An instance of the FlowLayout class positions objects on the frame in centered, typewriter fashion. Because the frame in Figure 9-3 has only one button on it, that button is centered near the top of the frame. If the frame had eight buttons, five of them may be lined up in a row across the top of the frame and the remaining three would be centered along a second row.
  • setLayout: Calling setLayout puts the new FlowLayout object in charge of arranging components, such as buttons, on the frame. (The new SimpleFrame object is calling its own setLayout method.)
  • setDefaultCloseOperation: Calling setDefaultCloseOperation tells Java what to do when you click the little × in the frame’s upper-right corner. Without this method call, the frame itself disappears, but the Java Virtual Machine (JVM) keeps running. If you use Eclipse, you have to halt the JVM by clicking the red square near the top of the Console view. (See Figure 9-4.)

    Calling setDefaultCloseOperation(EXIT_ON_CLOSE) tells Java to shut itself down when you click the × in the frame’s upper-right corner. The alternatives to EXIT_ON_CLOSE are HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, and my personal favorite, DO_NOTHING_ON_CLOSE.

    9781118407806-fg0904.tif

    Figure 9-4: Telling Eclipse to terminate the run of a Java program.

  • JButton: The JButton class lives in the javax.swing package. One of the class’s constructors takes a String instance (such as "Panic") for its parameter. Calling this constructor makes that String instance into the label on the face of the new button.
  • add: The new SimpleFrame object calls its add method. Calling the add method places the button on the object’s surface (in this case, the surface of the frame).
  • setSize: The frame becomes 300 pixels wide and 100 pixels tall. (In the javax.swing package, whenever you specify two dimension numbers, the width number always comes before the height number.)
  • setVisible: When it’s first created, a new frame is invisible. But when the new frame calls setVisible(true), the frame appears on your computer screen.

The SuppressWarnings annotation

Chapter 8 introduces the annotation — extra code that provides useful information about the nature of your program. In particular, Chapter 8 describes the Override annotation.

In this chapter, Listing 9-9 introduces another type of annotation: the SuppressWarnings annotation. When you use a SuppressWarnings annotation, you tell Java not to remind you that your program contains certain questionable code. In Listing 9-9, the line @SuppressWarnings("serial") tells Java not to remind you that you've omitted something called a serial
VersionUID field. In other words, the SuppressWarnings annotation tells Java not to display a warning like the one in Figure 9-5.

9781118407806-fg0905.tif

Figure 9-5: Without a SuppressWarnings annotation, Java warns you about a missing serialVersionUID field.

“And what,” you ask, “is a serialVersionUID field?” It’s something having to do with extending the JFrame class — something that you don’t care about. Not having a serialVersionUID field generates a warning, not an error. So live dangerously! Just suppress the warning (with the annotation in Listing 9-9) and don’t worry about serialVersionUID fields.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.125.51