Sun Java Solaris Communities My SDN Account
 
New to Java Programming Center

New to Java

Programming Center

Java Platform Overview | Getting Started | Learning Paths
References & Resources | Certification | Supplements




Contents
BACK<<Adding Functionality | Inner Classes

Do inner classes have direct access to instance variables and methods of the outer class?

An inner class has the special privilege of unlimited access to its enclosing class' members, even if they're declared private. By using an inner class for event handling, you enclose the code for handling user input neatly within an inner class, while using the outer class for the GUI components.

The next section shows you how to implement this functionality using inner classes.

More about Inner Classes

Inner Classes

Chapter 7: Inner Classes

How do inner classes work?

Inner Classes

Inner classes are defined within a class. In this case, the enclosing class is the Diver class and the inner class is the CheckBoxHandler class. There are four types of inner classes:

  • Simple inner classes
  • Inner classes within methods
  • Anonymous inner classes
  • Static inner classes

The Diver class encloses only a simple inner class. These are the basic rules:

  • An instance of an inner class can only exist within an instance of the enclosing class.
  • Other classes cannot access this inner class without creating an instance of the enclosing class.
  • The inner class has direct access to the instance variables and methods of the enclosing class without having to reference a handle or variable.
  • Inner classes can extend other classes as well as implement as many interfaces as necessary.
  • Inner classes can be defined as public, private, or protected.

In the case of this CheckBoxHandler inner class you give it private access, since it is only used in context with the Diver class.

For example:

private class GUIEventHandler implements ActionListener

Because the CheckBoxHandler class defines the functionality of the check boxes, it must implement the ItemListener interface. As with the ActionListener interface, you must implement any methods that ItemListener declares. Again, there is only one method:

itemStateChanged(ItemEvent e)

This method is invoked when an item has been selected or deselected, and performs the operations that need to occur when an item is selected or deselected: When a check box is selected, a check appears in the box. When deselected, the check disappears. To add to this, the Diver Data pane check box text turns blue when a check box is selected, and returns to the default color black when deselected.

Before delving into the pseudo code to plan the functionality, declare the inner class within the Diver class and provide the promised method declaration.


  1. Open the Diver.java file in your text editor.
  2. After the closing curly brace of the actionPerformed method, declare an inner class called CheckBoxHandler that implements the ItemListener interface:
  3.  private class CheckBoxHandler implements ItemListener 
     { // Opens inner class
     
  4. Declare an itemStateChanged method, using the correct signature provided in the Java API documentation:
  5. public void itemStateChanged (ItemEvent e)
    
  6. Save the file.

Pseudo code

List what should happen when the check boxes are selected or deselected:

If a check box is selected:

  • Determine which check box is selected
  • Make the text blue for that box

Or else if the box is deselected:

  • Make the text black

You can see at a glance that an if statement can handle the functionality, but this pseudo code reveals another keyword else. You could use several if statements, but using else shortens the lines of code. The if/else statement says do this if this occurs, or else do that.

To find out which check box fired an event, and then change the text for that box to blue, you use the getSource and getStateChange methods. The getSource method returns the object that fired an event, and the getStateChange method tells you if the event was a box being SELECTED or DESLECTED.

So you only have to be concerned with boxes that are selected, call the getSource method, which returns objects that fired an event. Check if the event is SELECTED, then assign it to a variable that references a JCheckBox object.

Because you aren't instantiating the JCheckBox class and creating a new object but are instead assigning a returned object and typing it as a JCheckBox object, you must explictly cast it as a JCheckBox object. You do this with the following:

JCheckBox source = (JCheckBox) e.getSource();

This line of code calls getSource, which returns an object that fired an event, casts it as a JCheckBox and assigns it to source, which is of type JCheckBox.

Next, the getStateChange method compares the object with a constant of the ItemEvent class that tells if the box is selected. These constants are static, so you need only use the class name and dot operator:

e.getStateChange() == ItemEvent.SELECTED

Now you can adjust your pseudo code more accurately with some real code:

JCheckBox source = (JCheckBox) e.getSource();
   if ( e.getStateChange() == ItemEvent.SELECTED )
      source.setForeground(Color.blue);
   else
      source.setForeground(Color.black);

Assigning and casting returned objects, then using the if/else statement allows you to write instruction for any check box that returns an object. The GUI is separate then from the functionality so you can add or remove more check boxes without having to change the code for the funcitonality.


  1. Open the Diver.java file in your text editor.
  2. Implement the itemStateChanged method, providing instruction for each check box object: check to see if the object equals each of your variables, and if it is selected:
  3. JCheckBox source = (JCheckBox) e.getSource();
       if ( e.getStateChange() == ItemEvent.SELECTED )
          source.setForeground(Color.blue);
       else
          source.setForeground(Color.black);
    
  4. Save the file.
Your class should match this Diver.java file.

Now you have an inner class that provides the functionality of the input components, while the enclosing class creates the GUI features that are presented to the user. If you need to change the functionality, you edit the inner class without affecting the enclosing class. Likewise, if you change the enclosing the class. the inner class remains unaffected, unless you add components that also need functionality added.

Because the inner class only works with an instantiation of the enclosing class, it is protected from other classes accessing it. Using inner classes also makes it easier to read the code. You know to work on the enclosing class for GUI features, or the inner class for functionality.

At this point, you have a program that displays labels and images, and provides text fields and check boxes for user input. When a user types data into the fields and presses Return or clicks the enter button, the data displays to the screen.

There remains a problem: Once the application is closed, the data is lost. To save data, you need to write the information to files or a database. Part 4 teaches Java I/O basics that includes reading from and writing to files.

Summary

Part 3 of the Dive Log tutorial reviewed Java programming concepts from Part 1 and Part 2 and introduced new ones.

User Input Objects

  • Text fields and check boxes are common components used to collect user data.
  • Preplan with pencil and paper or a drawing program to decide how you want to arrange user input components. Then decide which layout manager to use.
  • You can add many objects to a pane by building panels that use their own layouts.

Encapsulation and Access Control

  • Encapsulation works through hidden implementation and access modifiers.
  • Special methods are used to access data. These methods get or set data.

Event Handling Basics

  • Button and mouse clicks are examples of events that are fired from components.
  • To handle events, a class must implement the proper interface.
  • To register a component as an event listener, call the addxxxListener and pass in the proper event class that implements the promised method that defines the functionality.

The Dive Log application classes serve as introductory examples to Java programming. It is not a comprehensive guide to the Java programming language, but instead as an example of an application that teaches basic Java programming concepts. The concepts are repeated in subsequent Dive Log tutorial parts, as each class that makes up the tabbed panes is defined.

The Dive Log tutorial series covers more about methods, objects, and constructors in addition to creating other Swing GUI components and functionality. Each Dive Log class introduces new ideas as well as repeats what has been presented in earlier parts of the tutorial. In addition, each class representing a tabbed pane gets progressively more complex in terms of features and programming concepts.

Part 4: Using pull-down menus, adding scrollbars to a text area, and reading from files and writing to files.

About the Author

Dana Nourie is a JDC staff writer. She enjoys exploring the Java platform and creating interactive web applications using servlets and JavaServer Pages technologies, such as the JDC Quizzes, Learning Paths and Step-by-Step pages in the New to Java Programming Center. She is also a certified scuba diver and enjoys exploring the kelp forests and colorful tube anemone-covered floor of the Monterey Bay.


Reader Feedback

Tell us what you think of this tutorial.

[Duke]

Very worth reading Worth reading Not worth reading

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



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

Subscribe to the New to Java Programming Center Supplement to learn the basics of the Java programming language and keep up-to-date on additions to the JDC's New-to-Java Programming Center.

Oracle is reviewing the Sun product roadmap and will provide guidance to customers in accordance with Oracle's standard product communication policies. Any resulting features and timing of release of such features as determined by Oracle's review of roadmaps, are at the sole discretion of Oracle. All product roadmap information, whether communicated by Sun Microsystems or by Oracle, does not represent a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. It is intended for information purposes only, and may not be incorporated into any contract.