CPSC 170 Lab 3
Sorting and Mouse Events
As usual, create a lab3 subdirectory for today's lab, open this
document in Mozilla, and start emacs.
Sorting
File IntegerList.java contains a Java
class representing a list of integers.
Save this file to your directory, open it, and study it to be sure you
understand it.
The following public methods are
provided:
- IntegerList(int size) -- creates a new, empty list with capacity
size.
- void add(int value) -- adds the given item to the list. If the
list is already full, prints a warning message and leaves the list unchanged.
- void randomize() -- fills the list with random integers between 1 and
100, inclusive. Overwrites any elements already in the list.
- String toString() -- returns the list elements in a string suitable
for display.
File IntegerListTest.java contains a Java
program that provides menu-driven testing for the IntegerList class.
It creates an empty list of integers
and lets you
perform various operations on it.
Save this file to your directory as well,
then compile and run IntegerListTest to see
how it works. Add a few integers to the list, then print
the list. Then fill the list with random integers and print
it again. Now try to add another integer -- it won't let you, as the
list is already full.
Modify the code in these files as follows:
- Add a method void sortIncreasing() to the IntegerList class
that uses selection sort to sort the list into increasing
order. You may wish to refer to the code for selection sort in
Listing 9.9 of the text, but instead of including all of the sorting code
inside the loop
in the body of sortIncreasing, write and call the following
two methods:
- private int minIndex(int start) -- takes
an index start and returns the index of the
smallest value in the list starting at index start.
- private void swap(int i, int j) -- takes
two indices and swaps the values in the list at those indices.
As we discussed in class, your loop now just contains calls to
these two methods.
Note that you'll have to save the value returned when you call the
first method to pass to the second method.
Add an option to the menu in IntegerListTest to test your new method.
- Add a method void sortDecreasing() to the IntegerList class
that uses insertion sort to sort the list into decreasing order.
You may wish to refer to the code for insertion sort in
Listing 9.9 of the text (but note that it sorts into increasing order, not
decreasing).
Add an option to the menu in IntegerListTest to test your new method.
A Sorted Integer List
Now write a class SortedIntegerList that extends IntegerList.
SortedIntegerList should be just like IntegerList except that its elements should
always be sorted.
This means that when the user chooses to add an element, it should
be put into its sorted place, not just at the end. Similarly, when
the user chooses to fill the array with random elements, they should
be in sorted order. This means that SortedIntegerList must
override the add and randomize methods of the
IntegerList class.
Think carefully about how to implement these new methods. For example,
you could implement the new add method by writing all new code, or you
could use methods of the IntegerList class to first add the element, and then
sort the resulting array. This way your new method is just two calls, and
it doesn't even have to access the instance variables of the superclass.
To test your class, copy IntegerListTest.java into
SortedIntegerListTest.java and modify it to operate on a SortedIntegerList.
Choose a variety of options until you are convinced that your code
works correctly.
Print SortedIntegerList.java and IntegerList.java to turn in.
Mouse Events
You have written Java programs that respond to GUI events -- a
user pressing a button, checking a box, etc. Programs can also
respond to mouse events -- moving and clicking the mouse -- that
are not tied to any particular GUI component. Java divides
these into two categories: mouse events and mouse motion
events. A MouseListener (a class that implements the MouseListener
interface) must provide bodies for methods corresponding to each of the
mouse events. A MouseMotionListener (implementing the MouseMotionListener
interface) must provide bodies for methods corresponding to each
of the mouse motion events. These events are described
in section 7.9 of the text.
- File MousePlay.java contains a program that
displays a message saying when the mouse button is pressed and released.
It uses MousePlayPanel.java to define
the JPanel that is actually displayed. Save these files to your directory,
run MousePlay to see how it works, and open MousePlayPanel in emacs.
Note that MousePlayPanel has an
inner class MousePlayListener that implements MouseListener by giving
bodies for the five MouseListener methods. Even though
nothing is done when the mouse is clicked or when it enters or exits, those
methods still appear with empty bodies -- this is required for the
MouseListener interface to be implemented.
Modify MousePlayPanel so that it also prints appropriate
messages when the mouse
is clicked, when it enters the panel, and when it exits. Play with the
resulting program until you understand how the mouse events are
generated.
- Files Dots.java and
DotsPanel.java contain revised
versions of the code in listings
7.18 and 7.19 in the text. Dots draws a dot every time the uses presses
the mouse button; only the current dot is shown in the revised version.
Save these files to your directory and
run Dots to see how it works. Then modify DotsPanel as follows:
- Make the dots that appear alternately red and green. To do this,
you will need to make the following changes:
- Add an instance variable to hold the dot color.
- Add an instance variable to count the number of dots that
have been drawn.
- When the mouse is pressed, in addition to setting the draw
point you need to update the counter and change the dot color to
green if the counter is odd, to red if it is even. Then call repaint.
- Modify your code so that the dot is drawn where the mouse is
released, not where it is pressed.
Print DotsPanel.java to turn in.
- File Circles.java sets up a GUI that
creates and draws a circle as defined in Circle.java
of random size and color at each mouse press
Each
circle replaces the one before it. The code to handle the mouse
press and do the drawing is in
CirclePanel.java.
Save these files to your directory,
compile them and run them and experiment with the GUI.
Then modify these files as described below.
- This program creates a new circle each time -- you can
tell because each circle is a different color and
size. Write
a method void move(Point p) for your Circle class that takes a Point
and moves the circle so its center is at
that point. Now modify your CirclesListener class (defined inside
CirclePanel) so that
instead of creating a new circle every time the user presses the mouse,
if a circle already exists it moves the existing circle to the point where
the user pressed (the "presspoint"). If
no circle exists, a new one should be created at the presspoint.
So now a circle of the same color and size should
move around the screen.
- Write a method boolean isInside(Point p) for your Circle class
that takes a Point and
tells whether it is inside the circle. A point is inside the
circle if its distance from the center is less than the radius. Recall that the distance
between two points (x1,y1) and (x2,y2) is
sqrt((x2-x1)2+(y2-y1)2.
- Now modify the mousePressed method
of CirclesListener so that the GUI
behaves as follows:
- If there is no circle (i.e., it is null) and the user presses anywhere,
a new (random) circle should be drawn at the presspoint.
- If there is a circle on the screen and the user presses
inside that circle,
the circle should go away. (Hint: To make the circle go away, set it to
null and repaint.)
- If there is a circle on the screen and the user presses
somewhere else,
the circle should move to that point (no change from before).
So the logic for mousePressed should look like this:
if there is currently no circle
create a new circle at the presspoint
else if the click is inside the circle
make the circle go away
else
move the circle to the presspoint
repaint
- Add bodies for the mouseEntered and mouseExited methods
so that when the mouse enters the applet the background turns white,
and when
it exits the background turns blue. Remember that you can set the background
color with the setBackground method.
-
Now modify the code in CirclePanel.java so that a circle is drawn
when the user presses a mouse, but the user can drag it around as long
as the mouse button is depressed. If the mouse button is released and
then pressed again, it deletes or moves the circle as before.
You will need to make the following changes:
- In the CirclePanel constructor, make the CirclesListener object
listen for both mouse events and mouse motion events. Don't create
two separate listeners -- use the same
object for both.
- Make the CirclesListener class implement the MouseMotionListener
interface in addition to the MouseListener interface. This requires two
steps:
- Note in the header that CirclesListener implements MouseMotionListener.
- Add bodies for the two MouseMotionListener methods, mouseDragged
and mouseMoved. In mouseDragged, simply move the circle to
the point returned by the getPoint method of the MouseEvent and
repaint. (Remember that you already wrote a move() method for
the Circle class.) Provide an empty body for mouseMoved.
Print CirclesListener.java and Circle.java to
turn in.