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

CSC8303 -- Bioinformatics Programming in Java

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 what how netbeans supports it.

Some Administration

By now, you should have become familiar with netbeans. While netbeans supports BlueJ projects, it doesn't do so fully; the first thing that we will do is to change the project to a Netbeans native project. This will also copy all the files so giving you something to go back to if you need to 1.

act
  • Change to the Projects panel, on the left side of the screen.
  • Right Click on the shapes project -> Convert to Java SE Project. (view)
  • Fill in the boxes! It should end up like. (view)
  • From here, you can also copy a project if you want to store a version.
exclaim
  • You will now have two projects called "shapes". Make sure you work with the Java SE project and not the BlueJ one.
  • You can remove the BlueJ from Netbeans if you wish, but be careful not to delete the underlying code.

There is a further issue that we should deal with. 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 2. 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". Type a new package name "shapes" into the dialog, then click the "Refactor" button.

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.

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 netbeans (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 3.

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. Fill in the dialog (View). 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. (View)

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 netbeans 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);
    }

You should now have this.

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

  • There will be a little icon on the left of Circle. Click on this and select "Add import for shapes.Circle".
  • Find the change that netbeans has made for you. If you can't, ask the demonstrator. This change means "every time I say Circle, I really mean shapes.Circle".
  • Do the same for Canvas. In this case, make sure you get "shapes.Canvas" and not java.awt.Canvas which is a totally different class.

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, netbeans 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 4.

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 Shift-F6 (right-click Run "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
  • Right click on the source code editor in Grow.java.
  • Choose "insert code"->add property.
  • You should get a dialog defining what kind of property you want. Change these to reflect this screenshot.
  • 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 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. Going back to old code that was working is something that tends to happen a lot with programming. In the short term, keeping regular "check-points" of your code — copies made when it's all working — is a good idea. A much better way of doing this is to use Version Control systems; I use these all the time (these web pages are versioned), but they are a little complex to get started with. The advanced OO module shows how to use these.

2. 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 know, 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.

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

4. There are much better ways of doing this, using a Test Harness, often also know as Unit testing. Rather like version control, it's very good, but a little complicated, so we will not use it here. It will be covered in the advanced OO module also.


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