Concepts / Static and Non-Static Subroutines

Static and Non-Static Subroutines

Drawing instructions belong inside a subroutine definition, and that subroutine belongs inside a class definition.

  • Programming

Starting From a Working Sample

Suppose you want a Java program that puts a picture on the screen. The fastest route is not to start from a blank file. A sample program already exists that draws a picture of many colored disks, and your job is to replace what it draws with something of your own. The most useful question for a beginner is not how to write everything from scratch but where, inside a working program, the drawing instructions belong.

Run the sample program first and look at what it produces. Then, before reading the code in detail, ask yourself a simple question: if the picture is wrong, which lines of the program could be responsible? That question is the thread of this article. By the end you should be able to point to the region of code that controls the picture, and to tell apart the lines you are expected to change from the surrounding code you can leave alone.

Where the Drawing Code Lives

Java does not accept loose statements floating on their own. Drawing instructions have to sit inside a subroutine definition, and that subroutine definition has to sit inside a class definition. The class is the container for the whole program, and the subroutine is the container for the piece of work that draws the picture. A learner who places a drawing call directly in the class, outside any subroutine, has put it in a location the language will not accept as a running instruction.

In this sample the class is named SimpleGraphicsStarter, and the complete program is available in the source file SimpleGraphicsStarter.java. The drawing subroutine is the piece you touch. Everything else in the file is scaffolding the author has already written, and you do not need to understand it to make your own picture. The diagram below shows the containment: the file holds the class, the class holds the subroutine, and the subroutine holds the loop that does the drawing.

SimpleGraphicsStarter.javathe program fileclassSimpleGraphicsStartercontainer for the wholeprogramAuthor-writtenscaffoldingleave aloneDrawing loopruns 500 passesGraphics method callssetColor, fillOval,drawOvaldrawPicturesubroutinethe piece you editcontainscontainscontainscontainsrepeats on each pass
Where does the drawing subroutine sit relative to the class and the program file?

Reading the drawPicture Signature

The first line of a subroutine definition is called its signature. For the drawing subroutine, the signature is drawPicture(Graphics g, int width, int height). Notice what the signature does not contain: any drawing instruction. Its job is to name the values that arrive from outside the subroutine.

Definition

The signature of drawPicture supplies the graphics context g and the drawing area's width and height, so the body can use them without creating them.

Each parameter has a distinct role. The graphics context g is the object you call drawing methods on. The width and height tell you how large the drawing area is, so your drawing can adapt to it. You do not create these values inside drawPicture. They are supplied to the subroutine from outside, and the subroutine is free to use them in its body.

Best practice

When a value such as the drawing area size is handed to the subroutine through its parameters, use the parameter names inside the body rather than trying to rebuild those values yourself. The subroutine receives them already prepared.

One Subroutine, Many Calls

Definition

A subroutine is a block of code that can be called multiple times from different parts of a program. A subroutine does not run just because it exists in a program. It runs when the program reaches a point where it calls it.

Imagine a program that needs the same job done in three different places. You could copy the same lines of code three times, or you could write those lines once and let the rest of the program use them whenever they are needed. A subroutine is the second option. Because the same block can be called more than once, a single piece of code can serve many moments in a single run of the program.

java
Output
Hello
Hello
Hello
Notes on the code
  • printLine is defined once, inside the class, as a subroutine.
  • main calls printLine at three different points, so the same block runs three times.
  • This is an illustrative example written for this article, not the starter program's code.

Tracing main Through Repeated Calls

Follow the program's control step by step. The main part of the program reaches the first call, control moves into the subroutine, the subroutine finishes its work, and control returns to main. Execution then continues in main until it reaches the next call. The diagram traces this for three calls to the same subroutine. Each time, the subroutine body runs from its beginning, and each return sends execution back to the line in main that follows the call.

mainruns the programsubroutinesame block each time1. first call2. return to main3. second call4. return to main5. third call6. return to main
In what order does main call the subroutine, and when control returns to main after each call, where does execution pick up next?
Worked example

Tracing the Demo Program

Using the Demo program above, follow the order in which the statements run and state how many times the body of printLine runs.

  1. 1
    Start in main

    Execution begins with the first statement inside main.

  2. 2
    First call

    printLine() is reached, control moves into printLine, and the line printing Hello runs once.

  3. 3
    Return and continue

    printLine finishes, control returns to main, and execution moves to the next line in main.

  4. 4
    Second and third calls

    The same process repeats for the second and third calls, so the body runs again each time.

Result

The body of printLine runs three times, and the program prints Hello three times, once for each call made from main.

Reading Graphics Calls Like fillOval and setColor

The Graphics class provides the methods that actually put marks on the drawing area. Three appear in the sample. The setColor method chooses the color for the drawing calls that follow it. The fillOval method draws a solid oval, and drawOval draws only its outline. Each oval method takes four numbers. In the sample, those numbers are built from the disk center, with 50 subtracted from each coordinate and 100 used for both the width and the height.

gthe Graphics objectreceiving the callfillOvaldraws a solid ovalfour numbersset where and how big theoval is
In a call like g.fillOval with four numbers, which part names the object, which names the method, and which part controls the picture?

Ownership: main Versus drawPicture

If you compare the signatures of main() and drawPicture(), you will see that main() includes the word static and drawPicture() does not. The source explains that this reflects a difference in ownership: drawPicture is a subroutine in an object rather than in a class. The distinction between static and non-static subroutines is important, but the source sets it aside for now and says it will matter in Chapter 5.

Mistakes Beginners Make with Drawing Code

  • Common mistake

    Placing a drawing call directly in the class, outside any subroutine

    Why it fails

    Java does not accept loose statements floating on their own. Drawing instructions must sit inside a subroutine definition, which sits inside a class definition.

    Do this instead

    Move the drawing instructions into the body of the drawing subroutine.

  • Common mistake

    Moving setColor above the fill call and expecting random colors

    Why it fails

    setColor affects every drawing call that follows it, so the fill no longer uses the color the loop chose.

    Do this instead

    Check the order of setColor calls relative to the fill calls when a color looks wrong.

  • Common mistake

    Editing a part of the file other than the drawing body when the picture is wrong

    Why it fails

    The surrounding scaffolding was written by the author and is not where the picture is controlled.

    Do this instead

    When a picture is wrong, check the loop controls, the order of color changes, and whether you edited the drawing body.

  • Common mistake

    Assuming a subroutine runs just because it is written in the file

Predicting a Color Edit

What do you think happens?

If you move the black setColor call so that it sits above the fillOval call, what happens to the disks?

Reveal answer
Answer:

The disks are not filled with the random colors the loop chose.

setColor affects every drawing call that follows it. Moving the black color setting above the fill means the fill is drawn in black rather than the chosen random color.

EASY

Open the starter program and find the drawPicture subroutine. Identify the loop, and state what controls how many times it runs. Then change one number in the drawing body, predict in writing how the picture will differ, and run the program to check your prediction.

Hints
  • Look for the loop first, then find its control variable.
  • Predict only the change you expect to see, such as size or position, before running the program.

Subroutines in ThreeN2.java

The source describes ThreeN2.java, an improved version of the 3N+1 program introduced in Section 4.4, as a program that uses subroutines and prints its output in neat columns. The source does not list the individual subroutines inside ThreeN2.java or show their code, so this article does not describe them in detail.

What the source does establish is the reason the program uses subroutines. The first reason is code organization: separating work into named blocks makes the program easier to read and manage. The second is output formatting: the program prints its results in neat columns, and subroutines are part of how that formatting is achieved. When you open the file yourself, look for the places where the program calls a named block of code, and compare them with the places where it prints results.

Key Takeaways

  • Drawing instructions belong inside a subroutine definition, and that subroutine belongs inside a class definition.
  • The drawPicture signature supplies the graphics context g and the drawing area's width and height, so the body can use them without creating them.
  • A subroutine is a block of code that runs only when called, and it can be called many times from different parts of a program.
  • setColor affects every drawing call that follows it, so the order of lines determines the colors you see.
  • The static keyword in main() versus drawPicture() reflects ownership; its full meaning is deferred to Chapter 5.