Advanced Computer Programming Inf1BOb ject-Oriented Programming - - PDF document

advanced computer programming
SMART_READER_LITE
LIVE PREVIEW

Advanced Computer Programming Inf1BOb ject-Oriented Programming - - PDF document

Advanced Computer Programming Inf1BOb ject-Oriented Programming LAB 07 (week 8) - Widgets OOP Lab Exercise 3 (week 5) Widgets Hutchins 19th January 2007 7th-9th February, 2006 1 Introduction 1, In OOP assignment 2, you will learn how


slide-1
SLIDE 1

Inf1BOb ject-Oriented Programming

OOP Lab Exercise 3 (week 5) – Widgets

Hutchins 7th-9th February, 2006

1 Introduction

In OOP assignment 2, you will learn how to implement a simple class hierarchy — a hierarchy of shapes. This lab introduces a similar concept, called a widget. So what is a widget? You see them every time you turn on a computer. Widgets are the building blocks that make up a graphical user interface, or GUI, which is the part of the application that you see on the screen and interact with. Buttons, check boxes, menus, scroll bars, sliders, text fields etc. are all widgets. As a general rule of thumb, if you can see it on the screen, or click on it with your mouse, it’s a widget. Widgets are interesting for two reasons. First of all, if you want to write a program with a GUI, then you have to learn how to use them. Second, the invention of object-

  • riented programming itself was motivated in part by the need to deal with widgets.

Classes, inheritance, and class hierarchies have proved to be very useful mechanisms for organizing GUI libraries, and they are thus an excellent illustration of the benefits

  • f object-oriented programming.

Unfortunately, a modern widget library such as that supplied by Java is immensely complicated, and difficult even for experienced programmers to master. We will not be teaching the Java libraries in any detail in this course. Instead, we will provide you with a much smaller, simpler library, which was specially developed for Informatics 1B.

1.1 Events

Like shapes, each widget has a size and position on the screen. Each kind of widget is also responsible for drawing itself in an appropriate way — e.g. buttons draw text surrounded by a box, while scroll bars draw a rectangle with arrows. Most importantly, widgets respond to events. Every time the user moves the mouse, clicks on something, or presses a key, it generates an event. The Java libraries will process that event, and then call a method

  • f the appropriate widget. When you click on a button, the button object receives a

mouseClicked event. When you drag a scrollbar up and down, the scrollbar object receives a series of mouseDragged events. The Widget class defines a number of methods for handling events. In this lab, you will make a new kind of widget by creating a class which inherits from Widget, and then overrides these methods. The methods that you will override are described below. 1

Advanced Computer Programming LAB 07 (week 8) - Widgets 19th January 2007

1, this course.

slide-2
SLIDE 2
  • draw(g) is called whenever the widget needs to be drawn. A widget may need

to be drawn whenever a window appears, is uncovered, or is resized. A widget may also need to be re-drawn if the picture that it’s showing changes in some way; the redraw() command will force a widget to be drawn again.

  • mouseMoved(x, y) is called whenever the mouse cursor moves within the widget.

The x and y arguments specify the location of the mouse cursor.

  • mouseClicked(x, y, button, nclicks) is called whenever the mouse is clicked

within the widget. – x and y specify the location of the mouse. – button specifies which button was clicked: 1 for the left, 2 for the middle, and 3 for the right. – nclicks is 1 for a single click and 2 for a double click.

  • mouseDragged(x, y) is called whenever the mouse cursor moves within the

widget while one of the buttons is depressed.

1.2 Smiley Faces

A SmileyFace is a shape that consists of two eyeballs and a smile. Shapes the are the subject of OO assignment 2, but you don’t need to worry about that now. The SmileyFace class defines the following methods:

  • new SmileyFace(x,y,r) will create a new smiley face at position (x, y). The

radius of an eyeball is given by r.

  • draw(g) will draw the smiley face.
  • inside(x,y) will return true if the point (x, y) is inside the face.
  • move(dx,dy) will move the face by the offset (dx, dy).

If the shape was at position (x0, y0) before calling draw(), it will be at position (x0 + dx, y0 + dy) afterward.

  • getRadius() and setRadius() will get and set the radius of the eyeball, which

controls the size of the whole face.

  • lookAt(x,y) will cause the eyes to focus on the point (x, y).

Unlike widgets, shapes do not handle events or draw themselves automatically.

1.3 Downloading the Example Code

You can download the example code for the lab from: http://www.inf.ed.ac.uk/teaching/courses/inf1/oop/labs/Smiley.zip Create a new project named “Smiley”, and import the code from the .zip file as

  • normal. You will also need to create a run profile named “Smiley”, with “SmileyMain”

as the main class.

2 Making a smiling face

The example code will open a new window, and create a single widget: an instance of

  • SmileyCanvas. SmileyCanvas is a simple widget which provides a home in which smi-

ley faces can live. The first thing you need to do for this lab is put a SmileyFace onto the canvas. Go to the file SmileyCanvas.java, and make the following modifications: 2

Do the following: (1) Download the Smiley.zip file and unzip the file to a local directory "lab07" (2) Create a project named "Smiley" in NetBeans

  • Project > Project Manager > New
  • Right click on "Filesystems" and choose Mount > Lolal Directory > lab07

(3) Compile & Execute the project. When you execute the project, set Project Main Class to "SmileyMain".

slide-3
SLIDE 3
  • Add a new field named smiley of type SmileyFace.
  • In the constructor, initialize smiley to new SmileyFace(0, 0, 3).
  • Change the draw(g) method so that it calls smiley.draw(g).

Now run the program. You should see a smiley face!

3 Breathing some life into it.

Now we’ll make the face a bit more attentive.

  • Implement the mouseMoved(x,y) method so that the eyes of smiley track the

mouse cursor. (Hint: use the lookAt method.)

  • After changing the face, use the redraw() command to force the widget to

redraw itself. Now run the program. The eyes should follow the mouse cursor, as shown in the following screenshot:

4 Moving the face

Your next task is to make it possible to move the face by dragging it. The move(dx, dy) method will move the face, but dx and dy are offsets, not coordinates. In other words, the move command will slide the face in a particular direction; it will not move it to a particular location. You should implement mouseDragged(x,y) to move the face. Since x and y specify a location, not an offset, you must calculate the offset by comparing the current position of the mouse with the previous position of the mouse. Do the following:

  • Add two new fields named mouseX and mouseY, of type double.
  • Modify mouseMoved() so that it sets these two variables to the current position
  • f the mouse.

3

slide-4
SLIDE 4
  • Implement mouseDragged(x, y) so that it does three things:

– Moves the face by the proper offset, which is (x-mouseX, y-mouseY). – Set mouseX and mouseY to the new position of the mouse. – Call redraw(). You should now be able to drag the face around in the window.

5 Big and small faces.

Now that you have a properly attentive face, you need to provide a way to make it bigger or smaller. Ordinarily, you might add some buttons labeled “zoom in” and “zoom out”, but adding buttons means dealing with multiple widgets, and that makes things a little more complicated than necessary for our purposes. Instead, we’ll just use mouse clicks to control the face.

  • Implement the mouseClicked() method so that:

– The radius of the face increases by a factor of 0.9 when the user clicks the left mouse button. – The radius decreases by 1.1 when the user clicks the right mouse button.

  • Call redraw() after changing the face.

Now run the program. Does the face get bigger and smaller?

6 Multiple Faces

Now that you can move and resize faces, the next logical step is to put many faces

  • nto the same canvas. Instead of storing a single face, we will store an array of faces.

Unlike lists, arrays can only store a fixed number of items, and that makes it hard to add or remove faces while the program is running. So instead of trying to change the size of the array, we will simple pre-allocate an array that is big enough to hold as many faces as we are likely to need. 10 faces is sufficient for this lab. The array will be initialized at first to hold null values. Each time a new face is added, it is stored in the next available slot in the array. We also need to keep track

  • f the number of faces that are actually stored in the array, both because we need

to know where the next available slot is, and because we need to make sure not to put more than 10 faces in the array. The following diagram illustrates how the array works. To handle arrays, you must add the following fields and methods to the class: 4

slide-5
SLIDE 5

int numFaces; // the current number of faces SmileyFace[] faceArray; // the array of faces // initializes the array void initArray() { numFaces = 0; faceArray = new SmileyFace[10]; for (int i = 0; i < 10; i++) { faceArray[i] = null; } } // adds a single smiley face if there is room void addFace(SmileyFace f) { if (numFaces < faceArray.length) { faceArray[numFaces] = f; numFaces++; } } Now do the following:

  • Modify the constructor of SmileyCanvas so that it calls initArray() to initialize

the array, and then adds a single smiley face.

  • Modify draw() so that it draws all the faces in the array using a loop.
  • Modify mouseMoved() so that the eyes of all the faces track the mouse.
  • Comment out the code in mouseClicked() and mouseDragged() for now. We’ll

handle moving and resizing in the next section.

  • Modify mouseClicked() so that it creates a new face (using addFace) whenever

the user double-clicks the mouse. When you’re done, you should be able to create several faces which all look at the mouse.

7 Moving and Resizing Multiple Faces

Moving and resizing is a bit trickier now. Since there are multiple smiley faces in the window, you will need to figure out which face to resize or move. You will need to do the following to keep track of faces:

  • Add a field int currentFace. This variable keeps track of which face the mouse

is currently over.

  • Write a method int findFace(double x, double y) which searches through

all the faces, and returns the index of the first face it finds for which (x, y) is inside the face. If (x, y) is not in any of the faces, it should return -1. (Hint: Use the inside method.)

  • Modify mouseMoved() so that it sets currentFace to the result of findFace.

5

slide-6
SLIDE 6
  • Modify mouseDragged() and mouseClicked() to move and resize the current
  • face. If the current face is -1, these methods should not move or resize anything.

That’s it! You should now be able to create new faces, and move and resize existing

  • faces. And if two hours of staring at smiling faces proves too cheerful for you, you can

drown your misery in a pint after the lab. 6