程序代写 IAT 265 2

Mouse Interaction, Array, ArrayList, and Geom Shapes
______________________________________________________________________________________
SCHOOL OF floatERACTIVE ARTS + TECHNOLOGY [SIAT] | WWW.SIAT.SFU.CA

Copyright By PowCoder代写 加微信 powcoder

 Mouse Interactions
– MouseListener, MouseEvent, MouseAdapter
 Data structures
– Array for storing object collection – ArrayList for removing/adding
Drawing with Graphics2D and geoms
– Graphics2D’s draw/fill methods
– Classes in geom package for geometric shapes
10/1/2021 IAT 265 2

Mouse Interactions
 Two groups: clicking and moving
– Can be initiated using different mouse buttons
– Can be accompanied with modifier keys being pressed (Shift, Ctrl, Alt, etc. or their combination)
 There are two corresponding listeners: MouseListener and MouseMotionListener
10/1/2021 IAT 265 3

MouseListener Interface  What are the events of interest?
– mouseClicked
– Although it declares total five methods
 Callback method for mouseClicked
– public void mouseClicked(MouseEvent e)
 MouseEvent object
– Give access to event context (location, clicks,
modifier keys, etc….)
10/1/2021 IAT 265 4

MouseEvent class methods  getX(), getY() – returns coordinates of mouse
 getClickCount() – returns mouse clicks, e.g. 2 for double-clicks
10/1/2021 IAT 265 5

Let’s move ladybug to where we click
 JPanel should implement MouseListener
1. NeedstoimplementmouseClicked()–retrieves
mouse coordinates from MouseEvent object
2. Allotherinterfacemethodswillbeimplemented
as dummies (i.e. empty body)
3. JPanelwillregistertolistentomouseevents:
• By calling addMouseListener(MouseListener ml), a method belongs to java.awt.Component, of which JPanel is a subclass

Recap: Java Classes for Rendering
 Two types of GUI elements:
JPanel as a subclass of Component can call the method
Class that defined
addMouseListener (MouseListener ml)
October 1, 2021 IAT 265 7 • Source of the diagram: http://www.ntu.edu.sg/home/ehchua/programming/java/J4a_GUI.html#zz-2.2

BugPanel code
class BugPanel extends JPanel
implements ActionListener,
//implements *ALL* methods
declared by MouseListener
public void
mouseClicked (MouseEvent e){
bug.setLocationX(e.getX());
bug.setLocationY(e.getY());
//update the display
repaint();
MouseListener {
private Ladybug bug;
private Timer timer;
//constructors
public BallPanel() {
//register listeners timer.addActionListener(this); this.addMouseListener(this);
//All the rest is the same as
public void
mousePressed(MouseEvent e) {}
public void
mouseReleased(MouseEvent e){}

Our Goal next …
 Stop the bug when mouse is clicked on it
 Resume its moving when mouse is double
clicked on it
 Otherwise, reset its location to where mouse is clicked
10/1/2021 IAT 265 9

Stop ladybug when clicked
Let’s do some analyses:  How bug moves?
 How to stop it?
if(isMoving) bugX += speedX;
isMoving = false;
IAT 265 10
bugX += speedX;
– When clicked
public void mouseClicked(MouseEvent e){

Resume with double-clicks
 When double-clicked, we can check it out in the same mouseClicked method
public void mouseClicked(MouseEvent e) {
isMoving = false; //if single click
if(e.getClickCount() > 1) //if double click
isMoving = true;
10/1/2021 IAT 265 11

In Laybug class:
Reset its location when clicked off
 When mouse clicked off the bug’s body, we can simply call its location setter methods and set them to the mouse cursor position
public void setLocationX(int x) {
public void setLocationY(int y) {
 Per our analysis so-far, it feels like it would be convenient that we make Ladybug implement MouseListener, rather than JPanel
– Would this work? Let’s try!
10/1/2021 IAT 265 12

What went wrong …
 Remember addMouseListener is defined by Component, therefore can only be invoked by an object of its subclasses
– JPanel is such a subclass
 Ladybug is our custom class, an
independent class
– NOT a subclass of Component
10/1/2021 IAT 265 13

The correct way …
 Implement MouseListener with BugPanel  How do we know that the bug was clicked?
– We need to check the coordinates to see if mouse point hits the bug (at its current location)
– Which object knows where the bug was located?
• Ladybug! We need to check within Ladybug if it was hit
• Also isMoving should be a field of LadyBug, so that we can set it up inside the class  with a method like bugClicked(MouseEvent e)
10/1/2021 IAT 265 14

BugPanel code
Ladybug code
public class Ladybug {
public boolean checkBugHit(int x,
class BugPanel extends JPanel
implements ActionListener,
MouseListener {
//All the rest is the same as
boolean hit = false;
if(Math.abs(bugX – x) < before ... public void mouseClicked (MouseEvent e){ int mouseX = e.getX(); int mouseY = e.getY(); (bodyW/2)*scale && } bug.setLocationY(mouseY); if (e.getClickCount() > 1)
isMoving = true;
if (bug.checkBugHit(mouseX,
bug.bugClicked(e);
Math.abs(bugY – y) < (bodyH/2)*scale)) hit = true; } return hit; public void bugClicked(MouseEvent bug.setLocationX(mouseX); isMoving = false; Let’s drag the bug...  We need MouseMotionListener , which declared two methods – mouseDragged(MouseEvent e) - called for each new location while dragging – mouseMoved(MouseEvent e) - called for each new location while moving 10/1/2021 IAT 265 16 BugPanel code class BugPanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener { this.addMouseMotionListener(this); //All the rest is the same as public void mouseDragged(MouseEvent e){ if (bug.checkBugHit(e)){ bug.setLocationX(e.getX()); } } bug.setLocationY(e.getY()); public void mouseMoved(MouseEvent e){} 10/1/2021 IAT 265 17 Let’s change bug size ...  When clicked with Shift, enlarge  When clicked with Ctrl, shrink  How to check these modifier keys? 10/1/2021 IAT 265 18 Checking modifier keys  InputEvent class provides these relevant methods, and MouseEvent is one of its subclasses: – boolean isShiftDown() – boolean isControlDown() – boolean isAltDown()  To test for a flag, check if one of these methods tests true, e.g.: if(e.isShiftDown()) ... IAT 265 19 BugPanel code class BugPanel extends JPanel implements ActionListener, MouseListener { //All the rest is the same as before //enlarge by 20% //shrink by 20% public void mouseClicked (MouseEvent e){ if(bug.checkBugHit(e) && (e.isShiftDown()){ bug.enlarge(); if( bug.checkBugHit(e) && (e.isControlDown()){ bug.shrink(); //All the rest is the same as before 10/1/2021 IAT 265 20 Adapter classes for Listener Interfaces  Why Adapter classes? – When implementing Listener interface, you must implement all of its methods even though your program does not care about some of them – For convenience, Java provides supporting classes – Adapters, which provide "dummy implementations" for all the methods declared in the corresponding interface – By "extends" from the adapter class, you only need to override the method you want with your own implementation 10/1/2021 IAT 265 21 Adapters for listener interfaces Adapter class implemented WindowAdapter WindowListener MouseAdapter MouseListener MouseMotionAdapter MouseMotionListener KeyAdapter KeyListener FocusAdapter FocusListener 10/1/2021 IAT 265 22 MouseMotionAdapter class public interface MouseMotionListener { public void mouseDragged (MouseEvent e); public void mouseMoved (MouseEvent e); public abstract class MouseMotionAdapter implements MouseMotionListener { public void mouseDragged (MouseEvent e) { } public void mouseMoved (MouseEvent e) { } 10/1/2021 IAT 265 MouseAdapter class public Interface MouseListener { public void mousePressed (MouseEvent e); public void mouseReleaseed (MouseEvent e); public void mouseClicked(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e); public abstract class MouseAdapter implements MouseListener { //Can you fill in the implementation here? 10/1/2021 IAT 265 24 How to use Adapter classes for Listening?  Typically, we need to define our custom listener classes as inner classes by extending the relevant Adapter classes – This is necessary as listening is usually implemented in the panel class, which extends JPanel class already, and therefore cannot extend any other class – For inner classes though, you can define as many as necessary within the panel class, each of which can extend from a relevant Adapter class 10/1/2021 IAT 265 25 Define Custom Inner Listener classes  In BugPanel class, define two inner private classes for mouse and mouse motion listening that extend MouseAdapter and MouseMotionAdapter private class MyMouseMotionListener extends MouseMotionAdapter { private class MyMouseListener extends MouseAdapter { public void mouseClicked(MouseEvent e){ ... if(bug.checkBugHit(mouseX, mouseY) && e.isShiftDown(){ } bug.enlarge(); public void mouseDragged(MouseEvent e){ int mouseX = e.getX(); int mouseY = e.getY(); bug.setLocationY(mouseY); }} if(if(bug.checkBugHit(mouseX, mouseY) && e.isControlDown() { if (bug.checkBugHit(mouseX, mouseY)){ bug.setLocationX(mouseX); bug.shrink(); } } bug.setLocationY(mouseY); if (bug.checkBugHit(mouseX, mouseY)){ bug.clicked(e); bug.setLocationX(mouseX); Instantiate and add Custom Listener object  In BugPanel’s constructor, instantiate the two custom mouse listener classes and add them to BugPanel public class BugPanel extends JPanel implements ActionListener { ... //here is the same as before public BugPanel(){ ... //here is the same as before MyMouseMotionListenermyMoMoLsner =newMyMouseMotionListener(); addMouseMotionListener(myMoMoLsner); MyMouseListener myMoLsner = new MyMouseListener(); addMouseListener(myMoLsner); } 10/1/2021 IAT 265 27 Recap: Array  An array is a contiguous collection of data items of a single type – An array stores a list of values (aka elements) – Values are accessed by index numbers • Array index counts from 0, and ends at array_length-1 – You can get the length of an array by: arrayName.length 10/1/2021 IAT 265 28 Array of Primitives  int [] nums = new int[7] ; 10/1/2021 IAT 265 Syntax for creating an array of primitives // declare a double array double[] floatArray; // allocate memory space for the array floatArray = new double[5]; Name: floatArray, Type: double[] null 01234 01234 01234 // set first element floatArray[0] = 3; // set third element floatArray[2] = 5; 10/1/2021 IAT 265 30 Array of objects  Instantiate and initialize the array itself: Dog[] pets = new Dog[7];  It starts as an array of null reference for each element 10/1/2021 IAT 265 Array of objects Dog[] pets = new Dog[7] ; //Initialize each elements pets[0] = new Dog(); pets[1] = new Dog(); If you forget this step  Null pointer exception!! Case study: handle a collection of bugs  Create a collection of bugs with different sizes and random movement  Involve arrays, randomness, transformations, and saving/restoring transform attributes IAT 265 33 First off ...  For convenience, let’s create a Util class, which defines a random method with range parameters: public class Util { public static double random(double low, double high) { }return low + Math.random() * (high - low); public static float random(float low, float high) { }return (float) (low + Math.random() * (high - low)); 10/1/2021 IAT 265 34 Create an Array of Bugs in BugPanel //declare the Bug array private Ladybug[] bugs; Private final static int BUG_COUNT = 30; //constructor: create the Bug array bugs = new Ladybug[BUG_COUNT]; //and fill it with Bug objects for (int i = 0; i < bugs.length; i++) { float scale = Util.random(0.4f, 1.2f); float spdX = Util.random(-2.0f, 2.0f); float spdY = Util.random(-2.0f, 2.0f); float locX = GARDEN_X + Util.random(50, GARDEN_W); float locY = GARDEN_Y + Util.random(50, GARDEN_H); bugs[i] = new Ladybug(new Pvector(locX, locY), new Pvector(spdX, spdY), scale); 10/1/2021 IAT 265 35 Loop through the array to render and move these bugs public void paintComponent(Graphics g) { //whatever done before //Loop through the array to draw the bugs one by one for (int i = 0; i < bugs.length; i++) { bugs[i].drawBug(g2); public void actionPerformed(ActionEvent e) { //Loop through the array to move the bugs one by one for (int i = 0; i < bugs.length; i++) { } bugs[i].move(); repaint(); 10/1/2021 IAT 265 36 Summary on Array  Arrays are collections of data of certain type, which is specified when the array is declared  Each array must specify a size when declared  An array’s size can be retrieved with arrayName.length  For Array of objects – When we declare and initialize an array of objects, the array is empty. it has a size, but doesn't contain any object yet but null – Not until we've initialized each element of the array can we say that our array contains objects – Only when each element in the array has be initialized with an object, we can then use this array in other portion of our program 10/1/2021 IAT 265 37 What if number of objects is changing?  Say we want to remove by double-clicking the bug, add Ladybug by double-clicking the panel  When storing bugs in an array, there are several problems: – Remove: we need to either set array cell to null or set a dead flag in Bug to avoid its drawing/moving/interacting in frame looping – Where in the array to add a new bug? Either fill in null spots or replace dead ones – What if the array is full and we want to add new ones?  If an array is causing trouble, is there other way to store our objects? 10/1/2021 IAT 265 38 A more flexible alternative: ArrayList  It’s a resizable array that holds objects – Can add and delete things without worrying about declaring the size  The main methods we care about are: add(Object o), get(int i), remove(Object o), and size() – Unlike an array, you call ArrayList’s size() method to get its length 10/1/2021 IAT 265 39 Note to add(Object o)method  The parameter type of add method is Object – Object is the root of Java class hierarchy  every Java class has Object as the ancestry superclass (implicitly!) – When a parameter is typed with Object, you can pass in an object of any class (broadest Inclusion Polymorphism!!)  So, to initialize our bugs ... ArrayList bugs = new ArrayList(); for(int i = 0; i < count; i++){ bugs.add(new Ladybug(...)); 10/1/2021 IAT 265 40 Getting things out of an ArrayList  get(int i) – returns the ith object (starting with 0)  But the following doesn’t work! Ladybug bugi = bugs.get(i); bugi.drawBug(g2); 10/1/2021 IAT 265 41 Ways to deal with Type issue for ArrayList  This is because: things are placed into an ArrayList as Object type, and taken out as Object type as well – agnostic to their more specific type – Object doesn’t know any method it doesn’t define  Generally there are two ways to deal with the issue: – Type Casting back to the more specific type when you take things out of an ArrayList – When you create an ArrayList object, specify the type with <> operator
10/1/2021 IAT 265 42

Examples for both
 Type Casting back to the more specific type: for(int i=0; i < bugs.size(); i++){ Ladybug bugi =(Ladybug)bugs.get(i); bugi.drawBug(g2);//works fine now!  Specify Type when declaring ArrayList objects: ArrayList bugs = new ArrayList ();
10/1/2021 IAT 265 43

Destroy bugs with ArrayList’s remove method
 When a Bug object is double-clicked, we need to destroy it
– Add a destroy method to the BugPanel class:
bugs.remove(b); //note we do not need to know the index
 By doing so, any dead one would be removed  ArrayList’s size() method will return new size
10/1/2021 IAT 265 44

Case study: Remove/Add a Bug via ArrayList
 By double clicking on the bug/window
10/1/2021 IAT 265 45

Define Custom Inner Listener classes
 In BugPanel class, define an ArrayList to hold bugs
 In the inncer class’ mouseClicked method to handle bug
removal/addition with double click
pubic class BugPanel implements ActionListener {
private ArrayList bugs;
//all others the same as before
public BugPanel(){
bugs = new ArrayList();
for (int i = 0; i < BUG_COUNT; ++i) { ... //same as previous example bugs.add(new Bug(loc, vel, scale)); }} public void mouseClicked(MouseEvent e){ if (e.getClickCount() < 2) return; //done if no double click Bug bugi = null; for (int i = 0; i < bugs.size(); ++i){ if (bugi != null) //if hits a bug bugs.remove(bugi); else //Or hits none } respawNewBug(); if(bugs.get(i).checkBugHit(e.getX(), e.getY())){ bugi = bugs.get(i); //if identify one } break; //break out of loop Summary on ArrayList  ArrayList allows you to create a dynamically resizable list  ArrayList elements are typed with Java root class Object by default , as a result it is agnostic to the specific type of objects it holds  You can choose to specify the type when declaring an ArrayList object with
 Otherwise when getting elements out of an ArrayList you must cast them back to their specific type before you can call their methods or access their fields
10/1/2021 IAT 265 47

Recap: Graphics2D
 Graphics2D class is a newer, more powerful
version drawing tool than Graphics class
– It draws or fills primitives in a more flexible way
– It can draw more primitives than its parent class, e.g. curves
– It has functionality for checking intersection and containment between objects
(Done with the followings)
– It can draw with better quality (anti-aliasing)
– It provides transformation functionalities (translate,
rotate, scale etc.) that its parent class is unable to do
October 1, 2021 IAT 265 48

Review: Graphics’ methods for drawing primitives
– drawLine(int x1, int y1, int x, int y2) – drawRect(int x1, int y1, int w, int h)
– fillRect(int x1, int y1, int w, int h)
– drawOval(int x1, int y1, int w, int h)
– fillOval(int x1, int y1, int w, int h)
– drawArc(int x1, int y1, int w, int h, int startAngle, int arcAngle)
– fillArc(int x1, int y1, int w, int h , int startAngle, int arcAngle) – drawPolygon(int xArray[], int yArray[], int numPoints)
– fillPolygo(int xArray[], int yArray[], int numPoints)
 Have you noticed any problem with these drawing methods
October 1, 2021 IAT 265 49 References: Images from 7 Surefire Articles to Help You Save Money at the Gas Pump
of Graphics object?

Working with Graphics2D and Geometric Classes
 It would be desirable to have only two methods instead:
– draw (shape); – fill (shape);
 Where shape is a geometric object passed in as argument, rather than coupled with method name
October 1, 2021 IAT 265 50 References: Images from https://www.redfynn.com/gas-station

What is this?
Shapes in java.awt.geom
 Sowhatwecandonowisto:
– create geometric objects by using classes in the java.awt.geom package – renderthemwithGraphics2D’sdraw()and/orfill()methods
 To begin we need to obtain a Graphics2D object, create a Shape object , and then draw/fill it out, e.g.
public void paintComponent (Graphics g) {
Graphics2D g2 = (Graphics2D) g; //type Casting Ellipse2D.Double eclipse = new
Ecllipse2D.Double(50, 50, 100, 100); g2.draw(eclipse);
October 1, 2021 IAT 265 51

Inner Classes for Geometric Primitives in java.awt.geom
 It’s a norm for the java.awt.geom package to use static inner classes to represent shapes with different precisions
 For instance, Ellipse2D is an abstract class * representing an ellipse defined by a

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com