Top: Index Previous: Hello and Resources Up: Index Next: Conditionals and Inheritance

CSC8317 -- Introductory Programming for Bioinformatics

Loops and Refactoring

The purpose of this exercise is:

exclaim
  • To gain familiarity with control flow constructs in Java.
  • Add some properties to a Class.
  • Understand refactoring and see how Eclipse supports it.

Some Administration

By now, you should have become familiar with Eclipse, but we need to tidy up a little after the import from our BlueJ package. The Shapes package has been somewhat naughty; it's using what is called the default package. This is considered bad practice. The problem is this; a name like "Circle" is rather too common and might occur anywhere. Java's package system adds more information to prevent these name clashes 1. In fact, the Shapes package has a name class; there is another class called Canvas in Java. You can read more about packages if you wish. We will create a few more of these as time goes on.

act

  • In the projects panel, open Source Packages-><default package>.
  • Select all the *.java files.
  • In the menu, select "Refactor->Move". Click on Create Package, type a new package name "shapes" into the dialog. Then "Finish", and "Ok" the second dialog.

If you have done it right, all your classes should now be in the shapes directory. Check with the demonstrator if you are not sure. Run the class Automate to see if it all still works.

exclaim
  • You now have a shapes project with a shapes package in it. Don't get the two confused.
  • Packages are part of the Java language. Projects are part of Eclipse (although other IDEs have something similar). Don't confuse these either.

Performing some animation

We are now ready to do something new. In the lectures, you should have heard about control flow constructs; these are ways in which you affect the way that the program runs. You can read the details of them all if you wish. In this exercise, we are going to mostly focus on the for loop. In this case, we're going to do an animation of sorts 2.

First, we want to create a new package; the functionality is going to depend on that in the shapes package, but it's not critical for shapes. So, it should be in a different package. Let's create a new package.

act
  • Right click on the shapes project (not the package!). Or alternatively, right click on "Source Packages". Choose New -> Java Package. Call it animate.
  • Now, we are going to create two new classes, one called Grow and the other GrowTest.
  • Right click on the animate package -> New -> Java Class. Do this twice, one for each class.

Now, we are going to animate a circle that starts off small and grows over time. For this, we need a bit of magic code.

act

Put these methods into Grow.java. Remember Eclipse will show you if you get anything wrong; this will happen next. Just ignore these for the moment.


    private void animateStep() {
        Canvas.getCanvas().wait( 50 );
    }

    private void eraseObject(Object erased) {
        Canvas.getCanvas().erase(erased);
    }

Now, we are going to create a new method or operation much like you have seen on the shapes Classes. In this case, it will be called animateGrowingCircle.

act Add the following declaration to Grow.java.
    public void animateGrowingCircle(){

    }
We are going to instantiate (make a new object) of the Circle class. Change your code to look like this.
    public void animateGrowingCircle(){
          Circle c = new Circle();
          c.makeVisible();
    }

Packages in Java are meant to separate out different functionality. But this has caused us a problem. Java now doesn't know what Circle you mean — it's looking for Circle.java in the same package and it can't find it. Likewise, for the Canvas class.

act Depending on exactly which keys you pressed, whether you used completion, Eclipse may or may not have fixed this for you. If you still have errors in your class, which you will see by the warning symbols on the left, click on them, and try and fix the problem.

If you do not have Warning symbols, then Eclipse will have added some code for your. Make sure that you work out what this is.

Okay, we are now nearly ready to try out the for loop. You have an object of the Circle class. You should know how to change it's size. And you should have read how to use a for loop.

act
  • Write a for loop which counts from 0 to 300.
  • Each step should reset the size of the Circle object.
  • After you have done this, call the animateStep method. This should look like this:
  animateStep();
  • Finally, after you have finished the for loop, add this code, just to tidy up.
  eraseObject( c );

Okay, so we now should have a proper method. Hopefully, Eclipse will not be signalling any errors. So, how do we test this. We can't run this Class directly. Instead, we will use a test class; something whose sole function is to test something else 3.

act Add the following code into GrowTest.java.
    public static void main(String[] args) throws InterruptedException {

        Grow g = new Grow();

        g.animateGrowingCircle();
        Thread.sleep(2000);

        System.exit(0);
    }
Now with GrowTest.java still selected, hit Ctrl-Shift-F6 (right-click Run As "GrowTest.java"). With a bit of luck, it should all work.

So, we now have an animated circle growing. Now, we are going to try something somewhat more complex.

act Using similar techniques as before, implement the body of this method
    public void animateGrowingThenShrinkingSquare(){
        // you code in here
    }

In this case, it should animate a square which should grow from 0 to 300 and then shrink again. You will need two for loops. Add this test code to GrowTest.java.

       public static void main(String[] args) throws InterruptedException {

        Grow g = new Grow();

        g.animateGrowingCircle();
        Thread.sleep(2000);

        g.animateGrowingThenShrinkingSquare();
        Thread.sleep(2000);
        System.exit(0);
    }

This is fine, but the code is a bit limited. What happens if we want to make the Circle or Square grow quicker? What happens if we want to change the maximum size? We can't change this because we have hard coded these values. Let's change the animation step first. We will do this by introducing a new variable.

act
  • Add to Grow.java.
   private int animateStep;
  • double click on animateStep so that it is highlighted.
  • hover over this, till a dialog pops up
  • select "Create getter/setter for..."
  • accept the default
  • You now need to use this property rather than the hard-coded "50". Change your animateStep method to look like this
     private void animateStep() {
        Canvas.getCanvas().wait(getAnimationStep());
     }
  • Now, we can change this property independently from object to object.
  • Try this code in GrowTest.java
       public static void main(String[] args) throws InterruptedException {

        Grow g = new Grow();

        g.setAnimateStep( 200 );
        g.animateGrowingCircle();
        Thread.sleep(2000);

        g.setAnimateStep( 0 );
        g.animateGrowingThenShrinkingSquare();
        Thread.sleep(2000);
        System.exit(0);
    }
  • Use the same technique to replace references to "300" as maximum size.
  • Change GrowTest.java so that the square only grows to 100, while the circle continues to grow to 300.
log Get Grow.java and GrowTest.java signed off. Together these make up the coursework for this part of the exercise.

1. I used to work at Manchester University. I still have an email address there. Unfortunately, while my name is relatively rare there is another Phillip Lord there; he is a building manager at the University. I still regularly get email about cleaning fluids. The problem isn't so bad now, because he is Phillip Lord at Manchester and I am Phillip Lord at Newcastle. The problem would be much more common if we just used firstname.lastname for the entire world.

2. I suspect that Pixar will have little to worry about.

3. There are much better ways of doing this, using a Test Harness, often also know as Unit testing. It's very good, but a little complicated, so we will not use it here.


Top: Index Previous: Hello and Resources Up: Index Next: Conditionals and Inheritance