pixel
pixel
header
    December 20, 2002    

In this Issue

imageJava Programming Language Basics
imageJava Bits
imageMaking Sense of the Java Class Libraries
imageProgram Challenge
imageFor More Information

Pixel

Java Programming Language Basics

Understanding Interfaces

Good object-oriented programming requires class designers to hide information that shouldn't be known to users of said classes. With the Java programming language, such access can be controlled through the help of keywords as private, protected, and public. These keywords control the visibility of variables and methods inside the class, but poor class design results in too much visible information and methods that aren't properly encapsulated.

One way of encapsulating behavior is through the use of interfaces. Interfaces provide a way of hiding which class performs a specific task by exposing specific behavior such a class must support. As a program evolves, you can change the implementation without requiring changes in the calling class since the behavior itself hasn't changed, only the class that implements that behavior.

One such place where interfaces are commonly used is in the Collections Framework. The framework defines a handful of key interfaces that are implemented by a larger group of classes. By just learning the key interfaces, you effectively have learned the entire framework, as the specific implementation classes typically don't matter from a design perspective.

For instance, the List interface defines an ordered collection of elements. Available implementations include ArrayList and LinkedList, where both implement the List interface. When your program needs to work with a List, it should not care if it is an ArrayList or a LinkedList, only that whatever class is used provides a known behavior. That behavior is the interface.

By having classes implement interfaces, and only exposing the interfaces to the outside world in a class design, you have effectively encapsulated your class definition so that changes to the underlying implementation should minimally affect the rest of the system.

Take for example an ArrayList and a LinkedList. Think of an ArrayList as a growable array object (that only stores objects, not primitive data). While the class implements the full List interface, its behavior is optimized for specific conditions.

For instance, if your program is to frequently provide random access to the data of the list, (for example, "show me item three, twelve, two, and twenty-five") the ArrayList class offers quick access to individual elements of the list. This quick access comes at a cost of slower operations for adding and removing in the middle of the list. If this latter behavior is what you desire, than the LinkedList class offers a better alternative. It provides quick sequential access, additions, and deletes, at a cost of slower random access.

When working with ArrayList and LinkedList, there are two ways of creating the objects:

List cityList = new ArrayList();
LinkedList peopleList = new LinkedList();

Both of these code snippet lines compile, but there is a significant difference between the two lines. Line 1 states that we're creating an ArrayList, but we only need to access the item as a List. Line 2 is practically the opposite. Yes, the LinkedList item is created, similar to the ArrayList. But, the declaration side says that the program can only access the linked list as a LinkedList, and that is the significant difference.

Understanding interfaces really comes into play when the user of the two lines decides that the "give me item n" behavior is more important than the remove (or add) item at position "m" task.

The peopleList variable was declared to be of type LinkedList. While this isn't wrong by itself, as you examine the bigger picture, you'll find that anywhere that peopleList was used could be treating the object as a LinkedList. If you find that methods specific to LinkedList were used, then that class breaks when you need to treat it as an ArrayList.

List peopleList = new ArrayList();

By learning to work with any object only through its interface, you find that you can change implementations after design with no code changes beyond the declaration. That's the beauty of interfaces. As the class was originally declared a LinkedList, the change to type List would mean that method calls like addFirst or addLast would be unacceptable since the "new" peopleList of type List has no such methods.

This interface-based design of code such as the Collections Framework permits anyone to write code in a looping construct without ever having to know what collection you're working with. The created class is then restricted to provide complete implementations of the interface. Barring that, the new code wouldn't compile.

To demonstrate, the following program creates a couple of collections. Each collection offers a system-defined Iterator so that each element of the collection can be visited. This iterator is then passed along to a helper routine where the individual elements of the collection are printed.

import java.util.*;

public class Interfaces {

   public static void main(String args[]) {
     Properties props = System.getProperties();
     Set keySet = props.keySet();
     dumpIterator(keySet.iterator());

     List list = Arrays.asList(args);
     dumpIterator(list.iterator());
   }

   private static void dumpIterator(Iterator itor) {
     // System.out.println(itor.getClass().getName());
     while (itor.hasNext()) {
       System.out.println(">> " + itor.next());
     }
     System.out.println("----");
   }
}

The fact that the class type of the Iterator is unknown is the beauty of interfaces. It doesn't matter. The only thing that matters is the fact that the iterator method returns an actual Iterator object. Thus, dumpIterator always provide the full implementation of the interface.

If you uncomment the println comment line in dumpIterator, you'll find that the name of the actual iterator class is Hashtable.Enumerator for the Properties' key set and AbstractList.Itr for the List. This fact doesn't need to be known and won't help the behavior of your program. What does matter is that whatever is returned by the iterator method of List and Properties implements the three methods of java.util.Iterator: hasNext, next, and remove. Without two of the three methods, the dumpIterator method would never work.

Pixel
Pixel

Java Bits

Creating Font Objects

The Font class represents fonts, which are used to render text in a visible way.

  • A character is a symbol that represents an item such as a letter, a digit, or punctuation in an abstract way.
  • A glyph is a shape used to render a character or a sequence of characters.
  • A font encapsulates the collection of glyphs needed to render a selected set of characters as well as the tables needed to map sequences of characters to corresponding sequences of glyphs.

The Font class represents an instance of a font face from a collection of font faces present in the system resources of the host system, such as Arial or Courier. There can be several Font objects associated with a font face.

All fonts have the following properties:

  • Family Name, such as Arial
  • Size, such as 14 point
  • Style, such as italics

Because the fonts installed on a user's computer may vary, it's a good idea to use the most common fonts, such as Helvetica, Arial, or Courier.

To create a Font object, call the Font class constructor:

public Font(String familyname, int style, int size)

The familyname string is the name of the font you want to use, such as Arial. The style refers to four available font style constants in the Font class:

  • Font.PLAIN
  • Font.BOLD
  • Font.Italic
  • Font.BOLD = Font.ITALIC

As an example, the Font constructor is called with the following:

Font font = new Font("Helvetica", Font.BOLD, 16);

Then call the setFont method on the object where the font is to appear, such as a button or label:

JLabel label = new JLabel("It was a stormy night.");
label.setFont(font);

You can use the setBackground and setForeground methods to set the font a specific color, which is the foreground, and set the background to a color to contrast with the font color.

This FontExample application illustrates:

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

public class FontExample extends JFrame
  {
    JLabel label1;
    JLabel label2;
    Font font1;
    Font font2;
    String message = "This is a font.";
    
    public FontExample()
    {
     font1 = new Font("Helvetica", Font.BOLD, 18);
     font2 = new Font("Arial", Font.ITALIC, 22);
     
     label1 = new JLabel(message);
     label1.setFont(font1);
     label1.setBackground(Color.WHITE);
     label1.setForeground(Color.RED);
     
     label2 = new JLabel(message);
     label2.setFont(font2);
     label2.setBackground(Color.WHITE);
     label2.setForeground(Color.BLUE);
     
     JPanel p1 = new JPanel();
     
     p1.setBackground(Color.WHITE);
     p1.add(label1);
     
     JPanel p2 = new JPanel();
     p2.setBackground(Color.WHITE);
     p2.add(label2);

     getContentPane().add(p1, BorderLayout.NORTH);
     getContentPane().add(p2, BorderLayout.SOUTH);
      
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     setBounds(100, 300, 300, 100);
     setVisible(true);
     setBackground(Color.WHITE);
     }//Close constructor
 
    public static void main(String args[])
      {
      FontExample fe = new FontExample();
      }
  }

When the application is run, it should look something like the example below:

Pixel
Pixel

Making Sense of the Java Class Libraries

The JCombo and JList Classes

The Swing library provides classes to create objects that display a list. A user can then select one or more items on the list depending which class was used to create the list object.

A JList list object can include icons, list events, and listeners, and allows a user to select one or more items.

The JComboBox object is good to use for short lists, where only one item is to be selected. In addition, a JComboBox item can be made editable.

The JList and JComboBox classes are found in the javax.swing package.

A JComboBox object uses a ListCellRenderer object to determine how the elements are displayed. It also uses a ComboBoxModel object to provide methods to access the combo box elements.

Created with the JComboBox class, combo boxes are a combination of an editable area (if you desire) and a drop-down list of selectable items. Instances of JComboBox are not editable by default, but are set to editable by calling the setEditable method.

To create a JComboBox, call one of the following constructors:

  • JComboBox(): Creates a default combo box.
  • JComboBox(ComboBoxModel aModel): Creates a combo box that takes its items from an existing ComboBoxModel.
  • JComboBox(Object[] items): Creates a combo box that contains the elements in the specified array.
  • JComboBox(Vector items): Creates a combo box that contains the elements in the specified Vector.

You can supply a String array or a Vector to create the list of items. Once the array or Vector is defined, you pass it to the JComboBox constructor:

String drinks[] = {"Orange Juice", "Apple Juice", "Grape Juice"};
JComboBox menu = new JComboBox(drinks);

After initializing a combo box with an array to provide items for the drop-down menu, you can set how many of those items display in the list at once. If there are more than the specified number, scroll bars appear for the user to view other items on the list. Set maximum rows by calling the setMaximumRowCount method and providing an int:

menu.setMaximumRowCount(3);

You can implement ActionListener, so that when the user makes a selection, the JComboBox fires an ActionEvent, and the actionPerformed method defines what happens as a result of this selection.

For instance, within the actionPerformed method, you might call the getSelectedItem method, which returns the currently selected item as a String.

public void actionPerformed(ActionEvent e)
   { 
              
     String result = 
        (String)menu.getSelectedItem();
    }

Another way to present a user with a list of data is by creating a JList object. The JList class is a direct subclass of JComponent. JList implements several interfaces: Accessible, ImageObserver, MenuContainer, Scrollable, Serializable.

JList doesn't support scrolling directly. If you create a JList with a long list of items, use the JScrollPane class so that the user can scroll down a long item list.

You need to initialize a JList object with some data because this class doesn't have methods that allow you to add or remove individual items of data. Generally, you supply an array of strings, or a Vector to hold the data items, which populate the JList object.

To create a JList, call one of the four constructors:

  • JList()
    Constructs a JList with an empty model.
  • JList(ListModel dataModel)
    Constructs a JList that displays the elements in the specified, non-null model.
  • JList(Object[] listData)
    Constructs a JList that displays the elements in the specified array.
  • JList(Vector listData)
    Constructs a JList that displays the elements in the specified Vector.

A JList object uses ListCellRenderer to determine how the list should be displayed, and a JListModel object provides methods to access elements of the list and provides listener interfaces. To manage currently selected items in the list, implement the ListSelectionModel.

The JList class also has many methods for working with the appearance of the list, adding or removing listeners, and getting or setting list properties.

  • addListSelectionListener(ListSelectionListener listener)
    Adds a listener to the list that's notified each time a change to the selection occurs.
  • setSelectionModel(ListSelectionModel selectionModel)
    Sets the selectionModel for the list to a non-null ListSelectionModel implementation.
  • setSelectionBackground(Color selectionBackground)
    Sets the background color for selected cells.
  • setSelectionForeground(Color selectionForeground)
    Sets the foreground color for selected cells.

The following application demonstrates how to create JComboBox and JList objects, and includes examples of calling the methods which are defined above.

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


public class ListObjects extends JFrame
 {
   JComboBox menu;
   JList menu2;
   JTextField tf1;

   public ListObjects()
    {
      super("Breakfast Club Menu");

	  //Array to be used in menu combo list
      String drinks[] =
         {"Orange Juice", "Apple Juice", "Grape Juice"};
      menu = new JComboBox(drinks);
      //Array to be used in menu list
      String foods[] =
        {"Pancakes", "Scrambled Eggs", "Breakfast Steak",
        "Waffles", "Fried Eggs", "Hash Browns", "Oatmeal",
        "Blueberry Muffin", "Omelet", "Toast", 
        "Breakfast Burrito",
 "Fruit Bowl"};
      //JList object creation and methods to customize properties.
      menu2 = new JList(foods);
      menu2.setSelectionMode(
         ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
      menu2.setSelectionBackground(Color.YELLOW);
      menu2.setSelectionForeground(Color.BLUE);

      //Register with listener
      ListSelectionListener lsl = new MyListener();
      menu2.addListSelectionListener(lsl);

      //Text field to display JList selection
      tf1 = new JTextField("Selection appears here . . .", 20);
      //Panel for combo box
      JPanel p1 = new JPanel();
	  p1.setBackground(Color.WHITE);
	  p1.add(menu);
      //Panel for JList object
      JPanel p2 = new JPanel();
	  p2.setBackground(Color.WHITE);
	  //Add the list to the panel through
	  //a scrollpane
	  p2.add(new JScrollPane(menu2));
      //Panel for text field
	  JPanel p3 = new JPanel();
	  p3.setBackground(Color.WHITE);
	  p3.add(tf1);


      //Get the content pane, add the panels, and

       //set the layout.

	  getContentPane().add(p1, BorderLayout.WEST);
	  getContentPane().add(p2, BorderLayout.CENTER);
	  getContentPane().add(p3, BorderLayout.SOUTH);


      //Setting details for the app frame
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setBounds(300, 400, 400, 300);
      setVisible(true);
      setBackground(Color.WHITE);

     }

     //Class to implement listener interface, and call

      //necessary method that gets the selection and

      /displays that selection in the text field.
     class MyListener implements ListSelectionListener
       {
         public void valueChanged(ListSelectionEvent evt)
           {
	     tf1.setText((String) menu2.getSelectedValue());
           }
       }

    public static void main(String []args)
     {

      ListObjects lo = new ListObjects();
     }

}//Close class

When you compile and run this application, you should get a result that appears something like the figure below:

Pixel
Pixel

Program Challenge

Create the EnumArray Application

  • Use the String[] argument to main as the basis.
  • Use the Enumeration interface to print each element of the array.

See a possible solution to the Challenge:

Pixel
Pixel

For More Information

Lesson: Interfaces

How to Use Lists

Advanced JList Programming

Class Font

Pixel
Pixel

Downloading the Java 2 Platform

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

Pixel
Pixel
Pixel

Reader Feedback

  Very worth reading    Worth reading    Not worth reading 

If you have other comments or ideas for future newsletters, please type them here:

 

Have a question about Java programming? Use Java Online Support.

Pixel
Pixel

Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:

- Core Java Technologies Newsletter. Learn about new products, tools, resources, and events of interest to developers working with core Java technologies.
- Wireless Developer Newsletter. Learn about the latest releases, tools, and resources for developers working on wireless and Java Card technologies and applications.
- Core Java Technologies Tech Tips (formerly JDC Tech Tips) Get expert tips, sample code solutions, and techniques for developing in the Java 2 Platform, Standard Edition (J2SE)
You can subscribe to these and other JDC publications on the JDC Newsletters and Publications page

IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies:
http://www.sun.com/share/text/termsofuse.html
http://www.sun.com/privacy/
http://developer.java.sun.com/berkeley_license.html


Comments? Send your feedback on the Java Technology Fundamentals Newsletter to: dana.nourie@sun.com

Go to the subscriptions page to subscribe or unsubscribe to this newsletter.

ARCHIVES: You'll find the Java Technology Fundamentals Newsletter archives at:
http://java.sun.com/developer/onlineTraining/new2java/supplements/


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

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

Sun Microsystems, Inc.
image
image