A common error in programs is loops that never terminate. Infinitely looping programs are easy to spot in BlueJ: the "candy-cane" (or, "barbershop pole") in the Project window just spins and spins. Unfortunately, a program waiting for input ellicits the same behavior. If the output (Console) window is occluded behind another window, you might not be aware that the program is awaiting input. First, let me talk about the situation where your program is infinite looping.
Try this: download and run the following code in BlueJ:
public class InfiniteLoop { public static void main(String[] args) { int x = 1; System.out.println("Running..."); while (x > 0) { if (x == -1) { System.out.println("x is -1"); break; } else { System.out.println("x is not -1"); } x++; } System.out.println("Terminating..."); } public static void inputThis() { int x; Scanner kbd = new Scanner(System.in); x = kbd.nextInt(); } }
The candy-cane should just loop and loop. Here is a screen shot of the Project Window with the candy-cane looping:
(By the way, your computer might be acting a bit sluggish right now. That's because the CPU is wasting a lot of time executing the infinite loop.) To suspend an infinitely looping program, right-click on the candy-cane. A pop-up menu should appear:
Selecting the menu item will halt the program. This is good to a point, but doesn't let you know where you were stuck in an infinite loop (there may be several loops in your program, for example). You can find out exactly where you are by using BlueJ's debugger. To see how this works, start the infinite loop again. Once the candy cane is spinning again, select the project window, then use the View menu to select "Show Debugger".
This will bring up a window that looks like this .
Okay, now click on the "main" entry, as indicated above, then click on the "Halt" button as indicated below, and the debugger window will change to something like:
At this point the candy cane should no longer be spinning (but will still be red).
Next, Click on the "Step Into" button in the debugger,
and your editor should pop up, with an arrow and a yellow highlight box showing the next line of code in your program that will be executed. (You might well be stopped at a different place in the program!)
At this point, you can continue to click on the "Step" button in the debugger. This will execute the next line of your program, and then stop. Using the debugger you can also examine the values of variables if you want.
Eventually, you will want to terminate your program, so click on the Terminate button. The candy cane should now be grey.
Unfortunately, this same process will not work if your program merely appears
to be infinite looping, but is actually merely waiting for input. To see what
I mean, try running the Infinite.input
method that is defined in
our class. Because this method doesn't print anything, there is no indication
in the Terminal Window that the program is waiting for input. Again, you'll
see the candy cane spinning. You might be confused and think that there was
an infinite loop. Consequently, you might--mistakenly--consider using the technique
I've just outlined to determine where the loop is in your code.
Let's try it; again, bring up the debugger, select main and click on the Halt button. You will see something that looks like this:
The Call Sequence shows what methods or functions are currently being evaluated by your program. You won't recognize the names of any of these, because they are indirectly invoked when you call nextInt(). Unfortunately, if there were more than two such instructions, you couldn't tell
which one. Why? Because clicking on Halt does NOT cause BlueJ
to display an arrow in the source code window indicating where the program is
waiting for input! This is a pity, because it sure would be
nice if BlueJ displayed an arrow at the readInt
line.Anyhow, at least you know that the program is waiting for input, and not infinite looping.
Even worse than that, clicking on Terminate does NOT actually cause the program to terminate!!! Doing so only "reactivates" the Halt button. You can alternately click on Halt and Terminate until you are blue in the face. No matter what, you still have to go to the Terminal Window and enter a value there. Yuck!!! (If you've already hit the Halt button when you type in the Terminal Window, you may have to click on Terminate to get the program to actually read the input you've placed in the Terminal Window.) Alternatively, you could instead kill BlueJ and restart it, but that's pretty darn ugly.
In general, you should always print a prompt immediately before getting any input. That would avoid all this confusion.