CS 136 - Lecture 17

  1. GUI Components in Java
    1. Layout managers
      1. FlowLayout
      2. BorderLayout
      3. GridLayout
      4. Mixing layouts
    2. Panels
    3. Example of Layout of GUI components
  2. Event-Driven Programming
    1. Events
    2. Event Handling with Listeners
    3. Who can be a listener?

GUI Components in Java

Look at the following code fragment. It is the beginning of the class ButtonDemo:
public class ButtonDemo extends Frame
{
    protected Button startButton, stopButton;
    public ButtonDemo()
    {
        super("Button demo");       // calls Frame constructor 
                                    // which adds title to window
        setSize(400,200);           // sets the size of the window
        
        // sets layout so objects added go from left to right
        // until fill up row and then go to next row
        setLayout(new FlowLayout());
        
        // create two new buttons w/labels start and stop
        startButton = new Button("Start");  
        stopButton = new Button("Stop");
        

        add(startButton);   // add buttons to frame
        add(stopButton);
        
        // create an object to listen to both buttons:      
        ButtonListener myButtonListener = new ButtonListener();

        // tell buttons that myButtonListener should be notified
        startButton.addActionListener(myButtonListener);
        stopButton.addActionListener(myButtonListener);
    }
...
}
Thus ButtonDemo is an extension of Frame (i.e., it represents a window) which has two buttons, startButton and stopButton.

The two method calls:

        add(startButton);   // add buttons to frame
        add(stopButton);
add the two buttons to the frame according to the rules for FlowLayouts, which essentially just add items from left to right until it runs out of space and then starts a new row of items.

Layout managers

Layout managers help the programmer lay out components so that they look good even if the user changes the size of the frame.

FlowLayout

The default Layout manager for applet and panels is FlowLayout, which simply lays out items from left to right. When there is no more space it starts a new row. Thus if an applet's width is decreased, items from one row may move down to a lower row.

As we have seen, a Frame can also be assigned this layout manager by executing:

    setLayout(new FlowLayout());

BorderLayout

The default layout manager for frames is BorderLayout, which provides a bit more control over placement by allowing the programmer to add components into one of 5 areas: North, South, East, West, and Center.

BorderLayout has two constructors:

public BorderLayout()

public BorderLayout(int horizGap, int vertGap)

// leaves given gaps between components.

The layout manager of an applet or panel can be changed to BorderLayout by executing:

 setLayout(new BorderLayout())

Components are added by using a more refined version of add:

add(Component comp, String direction)

Thus to add a button on the north, write

add(startButton, "North")

Note. all directions must begin with a capital letter or an error will occur.

Components added to "North" and "South" extend to the left and right edges, while those added "East" and "West" extend up and down to the components to the "North" and "South". The component in the "Center" fills the remaining space.

If one component is omitted, other components stretch to fill that space.

With the BorderLayout, components stretch to fill all of the container. As a result using this by itself can often make layouts look distorted.

GridLayout

GridLayout arranges components into evenly spaced rows and columns. Constructors include:
public GridLayout(int rows, int cols)
// Construct layout w/ given rows and columns

public GridLayout(int rows, int cols, int h, int v)
// Construct layout w/ given rows and columns, and
// horiz and vertical gaps of h and v between components

Executing

setLayout(new GridLayout(2,3))

divides the frame or panel into 2 rows and 3 columns. When "add" method is executed, components are added from left to right first across the first row, then second row, etc.

Mixing layouts

Most of the time, none of the three layout managers described above does exactly what you want them to do. However, you can build up from components called panels and canvases and then place the GUI components directly on those components.

Panels

A Panel is a type of container. GUI components can be added to a panel, which can itself be added to a frame (or indeed another Panel).

The constructor for a panel is:

public Panel()

Example of Layout of GUI components

See the examples available in the CS136 folder on Cider Press.

Event-Driven Programming

Event driven programming is based on an explicit or implicit loop and event queue. The idea is that the queue holds all events that have occurred and each time through the loop one event is removed from the queue and processed. Concurrently various devices generate events which are added to the queue. If the queue is ever empty the processing loop suspends until an event is added to the queue.

The event handling is built into Java and the programmer need not provide either the loop or queue. Instead events are delivered to objects which handle them.


Events

Events include such things as clicking on a button, making a selection from a list, clicking a mouse button, moving the mouse, depressing a key, etc.

All events inherit from Event from package java.awt. One subclass is AWTEvent. It and its subclasses can be found in the package java.awt.event.


Event Handling with Listeners

Java event handling is based on a delegation model. Every time an event occurs, all registered listeners are notified. Each event type has an associated listener type and there is an associated method for attaching listeners to each component.

For example, ActionEvents are sent to Action listeners, which are registered by executing an addActionListener(...) method.

An important feature of the Java 1.1. event model is that the container responsible for displaying a component (e.g., the frame containing a button) need not be responsible for handling events generated by that object. By assigning a listener to an object we can explicitly delegate responsibility for handling the events generated by the object.


Who can be a listener?

In the lab handout you'll see how to do this using inner classes and using separate listener classes. It is also possible to have the class containing the component be the listener.