Sun Java Solaris Communities My SDN Account Join SDN
 
Java Technology Fundamentals Newsletter_Index_2002

Java Technology Fundamentals Newsletter

 

New-to-Java Programming Center
Programming Center Supplement

Welcome to the Java Developer ConnectionSM New to Java Programming Center Supplement!

This monthly supplement provides a way for you to learn the basics of the Java programming language, discover new resources, and keep up-to-date on the latest additions to the JDC's New to Java Programming Center.

CONTENTS

1. Java Programming Language Basics

Using the this and super Keywords

2. Making Sense of the Java Class Libraries

The JFrame Class

3. Program Challenge

ExitableJFrame

4. For More Information

Links to articles, Tech Tips, trails, and tutorials that provide more information on the topics discussed here.

5. Program Challenge Solution and Explanation

Possible solution to the CopyFile program

Java Programming Language Basics

Using the this and super Keywords

Constructors are special methods used to create and initialize instances of classes. You can provide one or many constructors, depending on how many different ways you want to support initialization of a class.

When defining a constructor for a class, the constructor name must match the class name. Here, the Person class has one constructor that accepts a String argument:

class Person {
   String name;
   Person(String name) {
     this.name = name;
   }
}

To create an instance of the Person class, you call the constructor with the new keyword:

Person p = new Person("Ophelia Jones");

This creates a new Person instance, and that instance has its name initialized to the value Ophelia Jones.

Classes are not limited to just one constructor. As long as their argument lists are different, you can use multiple constructors in a class.

For instance, if you want to create a Person and don't know their name, you can provide a second constructor that accepts no arguments and provides a default value for the name:

lass Person {
   String name;
   Person() {
     this.name = "Jane Doe";
   }
   Person(String name) {
     this.name = name;
   } 
}

You use this to access the instance variable. Normally, you don't need to use this. However, when an instance variable and local variable share the same name, you must differentiate between the two by prefixing the instance variable access with the use of this.

There is one fault to this method of providing multiple constructors: all the initial code is duplicated in each constructor, only providing a specific name in the first. Instead, a more efficient way is to have the first constructor call the second constructor.

To call one constructor from another constructor, the first non-comment line of the constructor must be the this method, passing in the appropriate parameters, usually filling in those values with default settings.

Here, the no-argument constructor calls the other constructor by passing the default name through the this call. Now, all the initialization code is centralized in the second constructor.

If other settings for the class are needed, you only need to update the one constructor, not both:

class Person {
   String name;
   Person() {
     this("Jane Doe");
   }
   Person(String name) {
     this.name = name;
   }
} 

When creating a subclass, its constructor automatically calls the no-argument version of the parent class, unless you say otherwise. For instance, the following class defines a Soldier with name, rank, and serial number properties (the name coming from Person).

class Soldier extends Person {
   String rank;
   String serialNumber;
   Soldier(String name, String rank, 
                 String serialNumber) {
     this.rank = rank;
     this.serialNumber = serialNumber;
   }
}

Since the Soldier constructor doesn't say otherwise, the no-argument version of the parent class constructor is called to initialize the Person state. That means that all soldiers will have a name of Jane Doe as the class is currently written.

In order to correct this behavior, you explicitly call the superclass constructor that accepts the name parameter. This is done by adding a super() call as the first line of the constructor:

class Soldier extends Person {
   String rank;
   String serialNumber;
   Soldier(String name, String rank, 
                 String serialNumber) {
     super(name);
     this.rank = rank;
     this.serialNumber = serialNumber;
   }
}

Whatever you pass into the Soldier constructor call is passed into the Person constructor.

The use of the this and super calls is reserved for only the first line of a constructor. You cannot have both in one constructor call. If neither is present, an empty super call is assumed.

Making Sense of the Java Class Libraries

The JFrame class

A JFrame is a predefined class from the javax.swing package and is an extended version of java.awt.Frame. You use a JFrame to build a top-level window with a border, a minimize and maximize buttons, and a close box. In addition, a JFrame is a Swing container that holds other containers and components such as panels and menus through association with one of its sub-panes.

The JFrame class has four constructors in Java 1.3 to build a JFrame object:

  • JFrame()
    This is the default constructor, which creates an invisible JFrame and that doesn't have any other features.
  • JFrame(GraphicsConfiguration gc)
    This second constructor creates a JFrame in the specified GraphicsConfiguration of a screen device and with a blank title.
  • JFrame(String title)
    The third constructor accepts a String as an argument and creates a JFrame with a specific text title.
  • JFrame(String title, GraphicsConfiguration gc)
    This last constructor creates a JFrame with the specified title and the specified GraphicsConfiguration of a screen device.

Initialize a JFrame object, using the third constructor as follows:

JFrame f = new JFrame("A Frame Example");

Even more common, though, is using the keyword extends with a child class to JFrame to gain the benefits of inheritance, then calling the JFrame parent class constructor with:

super("A Frame Example");

  • getContentPane
  • getGlassPane
  • getJMenuBar
  • getLayeredPane
  • getRootPane

The frame is not visible until you make it so. To make your frame visible, call the show method and set it to true. This makes sure the frame appears in front:

setVisible(true);

You can also set the size of your frame by calling setSize and including the width and height:

setSize(350, 200);

To specify what happens when the user closes this frame, call the setDefaultCloseOperation method and specify one of the following choices:

  • DO_NOTHING_ON_CLOSE
    Requires the program to handle the operation in the windowClosing method of a registered WindowListener object. (Event handling will be covered in a future issue of the supplement.)
  • HIDE_ON_CLOSE
    This default behavior automatically hides the frame after invoking a registered WindowListener object.
  • DISPOSE_ON_CLOSE
    Automatically hides and disposes the frame after invoking a registered WindowListener object.
  • EXIT_ON_CLOSE
    Exits the application using the System exit method. Use this only in applications.

The following example demonstrates the concepts covered so far:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

// FrameExample inherits from JFrame
// through use of the extends keyword.
public class FrameExample extends JFrame
  { 
    // Variables for objects
    JButton button;
    JPanel buttonPanel;
    
    public FrameExample()
     {
       // Initialize the button and panel.
       button = new JButton("A Button Framed");
       buttonPanel = new JPanel();
       
       // Add the button to the panel
       buttonPanel.add(button);
       
       // Add the panel to the content pane
       // of the JFrame in the North region of
       // the default layout, in this case
       // BorderLayout.
       getContentPane().add(buttonPanel, 
         BorderLayout.NORTH);
       
       // To close the window
       setDefaultCloseOperation(EXIT_ON_CLOSE);
       // Sets the width and height of the frame.       
       setSize(350, 200);
       setVisible(true);
      }
      
      public static void main(String args[])
       {
        FrameExample fe = new FrameExample();
        } 
    }

Java Bits

Class Inheritance

Why write code from scratch when a similar object already exists? You shouldn't. Instead you can use the extends keyword to inherit the characteristics of an already existing class.

When you develop a class that inherits from another class, the class you are writing is the child or subclass--the class inherited from is the parent class. By using extends, your subclass inherits the fields and methods from the parent class. In addition, you can hide fields or override methods of the parent class to better suit the needs of your subclass.

For instance, read through the parent class and the subclasses below:

// Parent class that represents a basic
// vehicle feature and function.
class Vehicle
  {
    int wheels = 4;
    public void engineStart()
     {
       System.out.println("Engine started. . .");
      }
    public void drive()
     {
       System.out.println("Driving on the pavement 
         on " +  wheels + " wheels.");
      } 
  }

// Subclass that uses the parent class' features 
// and adds a method unique to this kind of vehicle.
class Car extends Vehicle
 {
    public Car()
    {
      System.out.println("I'm a car:");
     }
    public void doorLock()
     {
       System.out.println("Locking all doors.");
      }
  }

// Subclass that hides the field of the parent  
// class with its own more appropriate data, and   
// adds a method unique to this vehicle.   
class Motorcycle extends Vehicle
  {
    // Hides the data of the parent class.
    int wheels = 2;
    public Motorcycle()
     {
       System.out.println("I'm a motorcycle:");
      }
    public void riding()
      {
        System.out.println("Riding on " + wheels +
                             " wheels.");
      }
    public void doingaWheelie()
     {
       System.out.println("Riding only on one wheel!");
      }
   }
// Subclass with additional data, a method 
// that overrides the parent drive method, 
// then later calls the parent's drive method 
// within a method for this subclass.
      
class Truck extends Vehicle
   {
    String storageBed1 = "long bed";
    String storageBed2 = "short bed";
      
    public Truck()
      {
        System.out.println("I'm a truck.");
       }
    // This method overrides the parent class
    // drive method, printing different text.     
    public void drive()
      {
        System.out.println("Use either 4-wheel 
          or 2-wheel drive."); 
      }
    
    public void showFeatures()
      {
        // Use of the super keyword here calls the 
        // drive method of the parent class. If you
        // omit super, then drive() from this 
        // subclass is called.
        super.drive();
        System.out.println("I have a " 
          + storageBed1 + " for storage.");
       }
   }
// Class to instantiate the object listed above and
// call the parent classes as well as the subclass
// methods.             
public class VehicleTest
 {
  
   public static void main(String[] args)
     {
       Car aCar = new Car();
       aCar.engineStart();
       aCar.drive();
       aCar.doorLock();
       
       Motorcycle aMotorcycle = new Motorcycle();
       aMotorcycle.engineStart();
       aMotorcycle.riding();
       aMotorcycle.doingaWheelie();
       
       Truck aTruck = new Truck();
       aTruck.engineStart();
       aTruck.drive();
       aTruck.showFeatures();
     }
  }

Running VehicleTest results in the following:

I'm a car:
Engine started. . .
Driving on the pavement on 4 wheels.
Locking all doors.
I'm a motorcycle:
Engine started. . .
Riding on 2 wheels.
Riding only on one wheel!
I'm a truck.
Engine started. . .
Use either 4-wheel or 2-wheel drive.
Driving on the pavement on 4 wheels.
I have a long bed for storage.

As illustrated above, a subclass inherits fields and methods from the parent class, but sometimes you need to hide the parent data or override the parent methods to refine the subclass. Hiding data is done simply by using the same variable name and type. Overriding methods of the parent class is done using the same method name and signature. If you've overridden a parent method, then find you need to call the parent version of that method, use the super keyword and the dot operator.

Program Challenge: ExitableJFrame

When working with JFrame components, the default behavior when trying to close the frame is to hide itself, but not shut down entirely. Frequently, you'll want the application to shut down on close.

Create a parent class that shuts down the application on close.

  1. Create a subclass that has the behavior of exiting out of the application. Avoid calling System.exit yourself.
  2. Use the setDefaultCloseOperation method of JFrame to configure the behavior.
  3. Provide replacement constructors for all four of the JFrame constructors.

For More Information

Providing Constructors for Your Classes

Constructors

Managing Inheritance

Class JFrame

Part 2: Introduction to Inheritance, Panels, and Layouts

SuperExample

Program Challenge Solution

There are many different ways to implement this challenge. Here is one way that takes advantage of the frameInit initialization method. You could also initialize the setting in all four constructors.

import javax.swing.*;

public class ExitableJFrame extends JFrame {
   public ExitableJFrame() {
   }
   public ExitableJFrame(String title) {
     super(title);
   }
   public ExitableJFrame(GraphicsConfiguration gc) {
     super(gc);
   }
   public ExitableJFrame(String title, 
     GraphicsConfiguration gc) super(title, gc);
   }
   protected void frameInit() {
     super.frameInit();
     setDefaultCloseOperation(EXIT_ON_CLOSE);
   }
}

Downloading the Java 2 Platform

For most Java development, you need the class libraries, compiler, tools, and runtime environment provided with the Java 2, Standard Edition (J2SE) development kit.

IMPORTANT: Please read our Terms of Use and Privacy policies:

Have a question about programming? Use Java Online Support.

- Note -

Sun respects your online time and privacy. The Java Developer Connection mailing lists are used for internal Sun Microsystems purposes only. You have received this email because you elected to subscribe.

- Unsubscribe -

To unsubscribe to this newsletter, go to the subscriptions page uncheck the "JDC New-to-Java Supplement" checkbox, and click "Update".

- Subscribe -

To subscribe to other JDC mailings, go to the subscriptions page choose the newsletters you want to subscribe, and click "Update".

- Feedback -

Comments? Send your feedback on the JDC Newsletter to: jdc-webmaster

- Copyright -

Copyright 2001 Sun Microsystems, Inc. All rights reserved.
901 San Antonio Road, Palo Alto, California 94303 USA

This document is protected by copyright.

JDC New-to-Java Programming Center Supplement
January 2002

Sun, Sun Microsystems, Java, and J2SE are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.


1 As used on this web site, the terms "Java virtual machine" or "JVM" mean a virtual machine for the Java platform.