Untitled

Course Overview

  • Course Title: CSC 133

  • Subject: Object-Oriented Computer Graphics Programming

  • Instructor: Dr. Kin Chung Kwan

  • Institution: Computer Science Department, California State University, Sacramento

Inputs

  • Input Devices: Several types of inputs are utilized in this programming class, primarily:
      - Mouse/Touch
      - Keyboard
      - Gesture

Mouse Input

  • Mouse/Touch Interaction: Often referred to as Pointer.
      - Generates an ActionEvent upon being clicked or touched.
      - Utilizes Event-Driven Programming principles.

Types of Events

Event handling distinguishes between several types of pointer actions:

  • PointerPressed: Triggered by clicking the pointer on the screen.

  • PointerDragged: Triggered when moving the pointer on the screen after press.

  • PointerReleased: Triggered upon releasing the pointer from the screen.

  • LongPress: A long click on the screen (introduced after CN7.0).

Adding Event Listeners

  • The Component class provides the following methods for adding listeners:
      - addPointerPressedListener()
      - addPointerReleasedListener()
      - addPointerDraggedListener()
      - Each method accepts a parameter of type ActionListener.
      - Allows attachment of commands suitable for command design patterns.

Pointer Handling

  • Pointer Handling Area: The form container, which has a listener added to it, calls the actionPerformed() of the attached listener when clicked.
      - Listener Code:
        - Click action triggers: ActionEvent “Pointer Listener”
      - If there is no listener, clicking the container won’t invoke any actions.

ActionListener Interface

  • To create ActionEvent, implement the ActionListener interface:
      - Interface Structure:
    java interface ActionListener { public void actionPerformed(ActionEvent e); }     
      - The ActionEvent in the actionPerformed() method has two essential methods:
        - getX(): Returns the x-coordinate of the pointer location.
        - getY(): Returns the y-coordinate of the pointer location.

Pointer Listener Example Code

public class PointerListenerForm extends Form {
    public PointerListenerForm() {
        Container myContainer = new Container();
        PointerListener myPointerListener = new PointerListener();
        myContainer.addPointerPressedListener(myPointerListener);
    }
}

public class PointerListener implements ActionListener {
    public void actionPerformed(ActionEvent evt) {
        System.out.println(evt.getX() + " " + evt.getY());
    }
}

Listener Placement Question

  • Question: What happens if the listener is added to the form rather than the container?

  public class PointerListenerForm extends Form {
      public PointerListenerForm() {
          PointerListener myPointerListener = new PointerListener();
          this.addPointerPressedListener(myPointerListener);
          // ...[add containers and components to the form] 
      }
  }
  ```
- **Answer:** Clicking anywhere on the form, including the title bar area, will print the pointer values.

## ActionEvent Pointer Position from Button

- Question: What will `getX()` and `getY()` return if the action event is generated by a button?

java
myButton.addActionListener(…);

public void actionPerformed(ActionEvent evt) {
System.out.println(evt.getX() + " " + evt.getY());
}
  ```

  • Answer: The coordinates would return values such as:
      - 172, 68
      - 30, 62
      - 60, 96
      - 140, 70
      - 182, 108

Different Listeners for Pointer Events

  • Introduces two approaches for event listening:
      - Separate Listeners: Requires creating multiple listener classes for each pointer event type.
      - Single Listener: Utilizing a single listener that employs getEventType() from the ActionEvent.

Example Code with Multiple Pointer Listeners

public class MyForm extends Form implements ActionListener {
    public MyForm() {
        this.addPointerDraggedListener(this);
        this.addPointerReleasedListener(this);
        this.addPointerPressedListener(this);
        this.show();
    }

    public void actionPerformed(ActionEvent evt) {
        System.out.println(evt.getEventType());
    }
}

Event Type Enumeration

  • ActionEvent Type Specification:
      - Event types specified by ActionEvent.Type: Examples include:
        - Pointer: ActionEvent.Type.Pointer
        - PointerPressed: ActionEvent.Type.PointerPressed
        - PointerReleased: ActionEvent.Type.PointerReleased
        - PointerDrag: ActionEvent.Type.PointerDrag
        - etc.

Overriding Pointer Methods

  • When extending from a Component, override the following methods for pointer actions:
      - pointerPressed()
      - pointerReleased()
      - pointerDragged()

Best Practices

public class PointerContainer extends Container {
    public void pointerPressed(int x, int y) {
        // Custom action on pointer pressed
    }
    public void pointerReleased(int x, int y) {
        // Custom action on pointer released
    }
    public void pointerDragged(int x, int y) {
        // Custom action on pointer dragged
    }
}

Keyboard Handling

  • Key Binding: Assigns functions to specific keys on the keyboard.

Example Keyboard Configuration

  • Key Bindings example for movement control:
      - W: Move forward
      - S: Move backward
      - A: Turn left
      - D: Turn right

Keyboard Handling with ActionListener

  • Implementation Method:

  this.addKeyListener('key', actionListener);
  ```
- **Key Code and ActionListener:** Specifies the key to listen to and the corresponding action listener to handle the action.

# Key Listener Functionality

- **Behavior:** After adding a **KeyListener** to a form, the `actionPerformed` of the **ActionListener** is executed.

## Example Implementation of Key Listener

java
public class MyForm extends Form implements ActionListener {
Label label;
public MyForm() {
label = new Label("Waiting…");
add(label);
this.addKeyListener('w', this);
this.addKeyListener('a', this);
this.addKeyListener('s', this);
this.addKeyListener('d', this);
show();
}

public void actionPerformed(ActionEvent evt) {
    switch(evt.getKeyEvent()) {
        case 'w': label.setText("It is W"); break;
        case 'a': label.setText("It is A"); break;
        case 's': label.setText("It is S"); break;
        case 'd': label.setText("It is D"); break;
    }
}

}

# Example Using Command Pattern

java
public class KeyCommand extends Command {
Label label;
public KeyCommand(String command, Label label) {
super(command);
this.label = label;
}

public void actionPerformed(ActionEvent evt) {
    switch(evt.getKeyEvent()) {
        case 'w': label.setText("It is W"); break;
        case 'a': label.setText("It is A"); break;
        case 's': label.setText("It is S"); break;
        case 'd': label.setText("It is D"); break;
    }
}

}

public class MyForm extends Form {
Label label;
public MyForm() {
label = new Label("Waiting…");
add(label);
this.addKeyListener('w', new KeyCommand("w", label));
this.addKeyListener('a', new KeyCommand("a", label));
this.addKeyListener('s', new KeyCommand("s", label));
this.addKeyListener('d', new KeyCommand("d", label));
show();
}
}

## Handling Key Event Issues

- **Problem:** Use `evt.getKeyEvent()` to identify the key event type, which may lead to issues with keys not functioning as expected (e.g., 'q', 'p').

# Better Approaches

- **Override Methods from Form:** Instead of relying solely on `KeyListener`, override from the child class of `Form`:
  - `public void keyPressed(int keyCode) {}`
  - `public void keyReleased(int keyCode) {}`

# Best Example for Key Handling

java
public class MyForm extends Form {
public void keyPressed(int keyCode) {
System.out.println("Pressed " + keyCode + " = " + (char)keyCode);
someModel.doSomething();
}

public void keyReleased(int keyCode) {
    System.out.println("Released " + keyCode + " = " + (char)keyCode);
    someModel.doSomething();
}

}

# Gesture Recognition

### Gesture Overview

Gestures are essential for user interface interaction and include common actions such as:

## Pinching Gesture

- **Definition:** Moving two fingers closer together (pinch) or further apart (stretch).
- In the CN1 **Component** class, the pinch feature can be implemented using the `pinch(float scale)` method:

java
public boolean pinch(float scale){}
  ```

  • It is important to override this method while creating a custom container as it does not work within the Form class.

Example Implementation of Pinching

public class MyContainer extends Container {
    public boolean pinch(float scale) {
        System.out.println(scale);
        return true;
    }
}
public class MyForm extends Form {
    public MyForm() {
        setLayout(new BorderLayout());
        add(BorderLayout.CENTER, new MyContainer());
        this.show();
    }
}

Simulator Behavior for Pinching

  • In Simulator:
      - Assumes one finger is always at the top left corner of the screen.
      - Pinching: Right-click and move the mouse towards the origin.
      - Stretching: Right-click and move the mouse away from the origin.

Mac-Specific Gesture Handling

  • Challenge: Performing pinch actions can be difficult, typically requiring double-finger clicks and movement towards the top-left corner.

Pinch Scale Definition

  • Definition: Refers to the ratio of lengths from the top left to the new positions while pinching or stretching.

Panning Gesture

  • Definition: The action of dragging a finger across the screen.

  • In CN1, to implement panning:
      - Override the pointerDragged() method in the Container class:
    java public void pointerDragged(int x, int y) { System.out.println(x + "," + y); }   

Questions and Discussions

  • The floor is open for any queries regarding the discussed topics and implementations.