SDSU CS535 Object-Oriented Programming & Design
Fall Semester, 1996
Doc 23 AWT Buttons, Model-View

[To Lecture Notes Index]
San Diego State University -- This page last updated Nov 14, 1996
----------

Contents of Doc 23 AWT Buttons, Model-View

  1. References
  2. Very Short Overview of AWT Parts
    1. Buttons
      1. Handling Button Events
      2. Custom Buttons
  3. Separating the GUI from the Program
    1. Model-View
    2. Observable and Observer

Doc 23 AWT Buttons, Model-View Slide # 1

References


Core Java, Chapter 7

Graphic Java, Geary and McClellan, Chapter 4

Design Patterns: Elements of Reusable Object-Oriented Software, Gamma, Helm, Johnson, Vlissides, pages 293-304


Doc 23 AWT Buttons, Model-View Slide # 2Listen Here!

Very Short Overview of AWT Parts

Components

Components are basic UI things

Buttons, Checkboxes, Choices, Lists, Menus, and Text Fields
When a user activates one of these controls -- by clicking a button for example -- it posts an event (ACTION_EVENT). An object that contains the control can react to the event by implementing the action() or handleEvent() method.

Canvases and Text Areas
Ways of Getting User Input


Scrollbars and Labels

Doc 23 AWT Buttons, Model-View Slide # 3Listen Here!
Component Classes

Doc 23 AWT Buttons, Model-View Slide # 4
Containers: Windows and Panels

Containers contain components and containers

Window
Dialog, FileDialog, and Frame are subclasses
Provide windows to contain components


Panels
Group components within an area of an existing window
Container Classes


Doc 23 AWT Buttons, Model-View Slide # 5
Component
action(Event,Object)lostFocus(Event,Object)
addNotify()minimumSize()
bounds()mouseDown(Event,int,int)
checkImage(Image,ImageObserver)mouseDrag(Event,int,int)
createImage(ImageProducer)mouseEnter(Event,int,int)
createImage(int,int)mouseExit(Event,int,int)
deliverEvent(Event)mouseMove(Event,int,int)
disable()mouseUp(Event,int,int)
enable()move(int,int)
enable(boolean)nextFocus()
getBackground()paint(Graphics)
getColorModel()paintAll(Graphics)
getFont()paramString()
getFontMetrics(Font)postEvent(Event)
getForeground()preferredSize()
getGraphics()prepareImage(Image,ImageObserver)
getParent()print(Graphics)
getPeer()printAll(Graphics)
getToolkit()removeNotify()
gotFocus(Event,Object)repaint()
handleEvent(Event)repaint(int,int,int,int)
hide()repaint(long)
imageUpdate(Image,int, ...)repaint(long,int,int,int,int)
inside(int,int)requestFocus()
invalidate()reshape(int,int,int,int)
isEnabled()resize(Dimension)
isShowing()resize(int,int)
isValid()setBackground(Color)
isVisible()setFont(Font)
keyDown(Event,int)setForeground(Color)
keyUp(Event,int)show()
layout()show(boolean)
list()size()
list(PrintStream)toString()
list(PrintStream,int)update(Graphics)
locate(int,int)validate()
location()


Doc 23 AWT Buttons, Model-View Slide # 6Listen Here!

Buttons

Adding a Button to a Window
import java.awt.*;

class  ButtonExample  extends Frame
   {   
   public ButtonExample( int  widthInPixels, int heightInPixels )
      {
      setTitle( "Button Example" );
      resize( widthInPixels, heightInPixels );

      setLayout( new FlowLayout() );
      add( new Button( "Red" ) );
      add( new Button( "Blue" ) );
      
      show();
      }
   }

class TestButton
   {
   public  static  void  main( String  args[] )
      {
      new  ButtonExample(200, 50);
      }
   }
Button Methods
getLabel()setLabel(String)


Doc 23 AWT Buttons, Model-View Slide # 7
Layouts

Need to specify where items will appear in a window that changes size

Must work on different platforms:
PC, Mac, Unix, PDA, toasters, TVs

Layouts provide a flexible way to place items in a window without specifing coordinates

The default layout for a frame is BorderLayout


Doc 23 AWT Buttons, Model-View Slide # 8Listen Here!

Handling Button Events


The action method is sent when button has been pressed
import java.awt.*;

class  ButtonExample  extends Frame
   {   
   public ButtonExample( int  widthInPixels, int heightInPixels )
      {
      setTitle( "Button Example" );
      resize( widthInPixels, heightInPixels );
      setLayout( new FlowLayout() );
      add( new Button( "Red" ) );
      add( new Button( "Blue" ) );
      
      show();
      }

   public boolean action( Event processNow, Object argument )
      {
      if ( buttonPressed.equals( "Red" ) )
         setBackground( Color.red );
      else if ( buttonPressed.equals( "Blue" ) ) 
         setBackground( Color.blue );
      else return false;
      
      repaint();      // Show effect of color change
      return true;
      }
      
   public  static  void  main( String  args[] ){
      ButtonExample  window = new  ButtonExample(200, 50);
      }
   }

Doc 23 AWT Buttons, Model-View Slide # 9Listen Here!
Identifying Buttons by LabelJust Say No
class  ButtonExample  extends Frame
   {
   Button red = new Button( "Red" );
   Button blue = new Button( "Blue" );
      
   public ButtonExample( int  widthInPixels, int heightInPixels )
      {
      setTitle( "Button Example" );
      resize( widthInPixels, heightInPixels );
      setLayout( new FlowLayout() );
      add( red );
      add( blue );
      show();
      }

   public boolean action( Event processNow, Object argument )
      {
      if ( processNow.target == red )
         setBackground( Color.red );
      else if (  processNow.target == blue ) 
         setBackground( Color.blue );
      else return false;
      
      repaint();      // Show effect of color change
      return true;
      }
   }


Doc 23 AWT Buttons, Model-View Slide # 10
Paint vs. Repaint

repaint calls paint plus more
Don't call paint directly
import java.awt.*;

class  PaintRepaint  extends Frame{
   int drawPoint = 10;
   Button move = new Button( "Move" );
         
   public PaintRepaint( int  widthInPixels, int heightInPixels ) {
      setTitle( "PaintRepaint Example" );
      resize( widthInPixels, heightInPixels );
      setLayout( new FlowLayout() );
      add( move );   
      show();
   }

   public  void  paint(  Graphics  display  ){
      display.drawString(  "Hello World", drawPoint, drawPoint  );
   }
      
   public boolean action( Event processNow, Object argument ) {
      if ( processNow.target == move )
         drawPoint = drawPoint + 15;
      else return false;
      
      repaint();      // Show effect moving the text
      return true;
      }
      
   public  static  void  main( String  args[] ) {
      new  PaintRepaint(250, 150);
      }
   }

Doc 23 AWT Buttons, Model-View Slide # 11
Output
Starting Position
After Several Click on Move

Doc 23 AWT Buttons, Model-View Slide # 12Listen Here!
Problem

Big case statement!!

For each button we need an if statement

   public boolean action( Event processNow, Object argument )
      {
      if ( processNow.target == red )
         setBackground( Color.red );
      else if ( processNow.target == blue ) 
         setBackground( Color.blue );
      else if ( processNow.target ==  ok ) 
         //code here
      else if ( processNow.target == quit )
         //code here
      else if ( processNow.target ==  pause )
         //code here
      else if ( processNow.target ==  start )
         //code here
      else if ( processNow.target ==  green )


      etc.

Doc 23 AWT Buttons, Model-View Slide # 13Listen Here!

Custom Buttons

A Solution

Let button handle the event

Button events are first sent to the button

Can use action or handleEvent
class ColorButton extends Button
   {
   Frame windowToColor;
   Color paintColor;
   
   public ColorButton( String buttonName, Color colorToUse, 
                     Frame toColor )
      {
      super( buttonName );
      paintColor = colorToUse;
      windowToColor = toColor;
      }
      
   public boolean action( Event processNow, Object argument )
      {
      windowToColor.setBackground( paintColor );
      windowToColor.repaint();
      return true;
      }
   }

Note: argument will contain the label of the button!

Doc 23 AWT Buttons, Model-View Slide # 14Listen Here!
Using Custom Button Class

import java.awt.*;

class  ButtonExample  extends Frame
   {   
   public ButtonExample( int  widthInPixels, int heightInPixels )
      {
      setTitle( "Button Example" );
      resize( widthInPixels, heightInPixels );
      setLayout( new FlowLayout() );

      add( new ColorButton( "Red", Color.red, this ) );
      add( new ColorButton( "Blue" , Color.blue, this) );
      add( new ColorButton( "Green" , Color.green, this) );
      add( new ColorButton( "Yellow" , Color.yellow, this) );
      add( new ColorButton( "Dark Gray" , Color.darkGray, this) );

      show();
      }
   }
   
class TestButton
   {   
   public  static  void  main( String  args[] )
      {
      new  ButtonExample(200, 200);
      new  ButtonExample(200, 200);
      }
   }

Doc 23 AWT Buttons, Model-View Slide # 15Listen Here!
Output


Doc 23 AWT Buttons, Model-View Slide # 16Listen Here!

Separating the GUI from the Program

A Simple Example

Problem: create a simple counter that:
can increase
can decrease
can be reset to zero

Display the counter in a window and allow the user to increase or decrease the counter via buttons.


Doc 23 AWT Buttons, Model-View Slide # 17Listen Here!
A Poor Solution - The Window is the Counter!
class  BadCounterExample  extends Frame  {
   Button increase = new Button( "Increase" );
   Button decrease = new Button( "Decrease" );
   Button reset = new Button( "Reset" );
   int count = 0;
      
   public BadCounterExample( int  width, int height ) {
      setTitle( "Button Example" );
      resize( width, height );
      setLayout( new FlowLayout() );
      add( increase );
      add( decrease );
      add( reset );
      show();
   }

   public boolean action( Event processNow, Object argument ) {
      if ( processNow.target == increase )         count++;
      else if (  processNow.target == decrease )    count--;
      else if (  processNow.target == reset )       count = 0;
      else                               return false;
      
      repaint();
      return true;
   }

   public  void  paint(  Graphics  display  )  {
      display.drawString(  "The count is " + count , 50, 50  );
   }

   public  static  void  main( String  args[] ){
      new  BadCounterExample( 200,  100 );
   }
}

Doc 23 AWT Buttons, Model-View Slide # 18Listen Here!
Output After clicking Increase 6 times
What is Wrong with the about program?It works!
Doc 23 AWT Buttons, Model-View Slide # 19
Where is the code reuse?
Can it help in the following Situation?


* 3 different ways to display a counter

* Some counters have more than one display

* Some counters are grouped together

Doc 23 AWT Buttons, Model-View Slide # 20Listen Here!

Model-View


A Model is a system of objects that perform a task

A View:

Displays a representation of the model by asking model for values to display

Handles all interaction with user about the model


Keeping the model and view separate
Give flexibility in combining new views to a model
Allows multiple views on the same model

Doc 23 AWT Buttons, Model-View Slide # 21Listen Here!
Counter Model
class Counter
   {
   private int count = 0;
   
   public void increase() 
      { 
      count++; 
      }

   public void decrease() 
      { 
      count--; 
      }

   public void reset() 
      { 
      count = 0; 
      }
      
   public int value()
      { 
      return count; 
      }

   public String toString() 
      { 
      return String.valueOf( count ); 
      }
   }

Doc 23 AWT Buttons, Model-View Slide # 22Listen Here!
A View for the Model
class  CounterExample  extends Frame
   {
   Button increase = new Button( "Increase" );
   Button decrease = new Button( "Decrease" );
   Counter count;

   public CounterExample( int width, int height, Counter outside )
      {
      setTitle( "Model View Button" );
      resize( width, height );
      setLayout( new FlowLayout() );
      add( increase );
      add( decrease );
      
      count = outside ;
      show();
      }

   public boolean action( Event processNow, Object buttonPressed )
      {
      if ( processNow.target == increase )
         count.increase();
      else if (  processNow.target == decrease )
         count.decrease();
      else 
         return false;
      
      repaint();
      return true;
      }

   public  void  paint(  Graphics  display  )  
      {
      display.drawString(  "The count is " + count , 50, 50  );
      }
   }

Doc 23 AWT Buttons, Model-View Slide # 23Listen Here!
Driver ProgramTwo Views Two Models
class ButtonTest
   {
   public  static  void  main( String  args[] )
      {
      Counter test = new Counter();
      new  CounterExample( 200,  100, test );
      test = new Counter();
      new  CounterExample( 200,  100, test );
      }
   }


Doc 23 AWT Buttons, Model-View Slide # 24Listen Here!
How about Two Views, One Model?
class ButtonTest
   {
   public  static  void  main( String  args[] )
      {
      Counter test = new Counter();
      new  CounterExample( 200,  100, test );
      new  CounterExample( 200,  100, test );
      }
   }

What Went Wrong?

When view A changes the counter how does view B know to update?

Who's responsibility is it to notify B of the change?

Doc 23 AWT Buttons, Model-View Slide # 25Listen Here!

Observable and Observer

(Dependents)(Publish-Subscribe)

Class java.util.Observable
Observable object may have any number of Observers
Whenever the Observable instance changes,
it notifies all of its observers
Notification is done by calling the update() method on all observers.

Interface java.util.Observer
When implemented, this interface allows all classes to be observable by instances of class Observer

Doc 23 AWT Buttons, Model-View Slide # 26Listen Here!
java.util.Observable Methods

addObserver(Observer)
Adds an observer to the observer list.
clearChanged()
Clears an observable change.
countObservers()
Counts the number of observers.
deleteObserver(Observer)
Deletes an observer from the observer list.
deleteObservers()
Deletes observers from the observer list.
hasChanged()
Returns a true boolean if an observable change has occurred.
notifyObservers()
Notifies all observers if an observable change occurs.
notifyObservers(Object)
Notifies all observers of the specified observable change which occurred.
setChanged()
Sets a flag to note an observable change.

Interface java.util.Observer
update
Called when observers in the observable list need to be updated


Doc 23 AWT Buttons, Model-View Slide # 27Listen Here!
Simple Example
class SimpleCounter extends Observable{
   public int count = 0;
   
   public void increase() { 
      count++; 
      setChanged();
      notifyObservers(); 
   }
}
   
class SimpleObserver implements Observer  {
   String id;
   public SimpleObserver( String id ) {
      this.id = id ;
   }

   public void update( Observable sender, Object message ) {
      System.out.println( "From " + id + " New value " + 
         ((SimpleCounter) sender).count );
   }
}
   
class ObserveTest {
   public  static  void  main( String  args[] ) {
      SimpleCounter test = new SimpleCounter();
      SimpleObserver a = new SimpleObserver( "a" );
      test.addObserver( a);
      test.addObserver( new SimpleObserver( "b" ) );
      test.increase();
      test.addObserver( new SimpleObserver( "c" ) );
      test.increase();
      }
   }


Doc 23 AWT Buttons, Model-View Slide # 28Listen Here!
Running the Example
class ObserveTest {
   public  static  void  main( String  args[] ) {
      SimpleCounter test = new SimpleCounter();
      SimpleObserver a = new SimpleObserver( "a" );
      test.addObserver( a);
      test.addObserver( new SimpleObserver( "b" ) );
      test.increase();
      test.addObserver( new SimpleObserver( "c" ) );
      test.increase();
      }
   }
Output
From b New value 1
From a New value 1
From c New value 2
From b New value 2
From a New value 2


----------