• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Java Class hangs after run

 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hey guys -- I was referred here by the Head First Java book. I'm doing pretty well and working my way through the beatboxing project.

I'm having just one problem and I had it earlier on another class file. My program compiles completely, and then runs w/o any errors. The only problem is that after the program is done, it just sits there -- almost like it wont finish the main method and exit the program.

Here is my code -- straight out of the book, so I'm wondering if it's just me being a beginner. I'm using JCreator to write and compile my code, but I've had similar problems using javac in command line.



You might not even need to look at my code to know my problem, but its frustrating me. I appreciate the help. If anyone has HF Java the code can be found on page 392.

Thanks
 
Ranch Hand
Posts: 624
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Donald Hume:
...almost like it wont finish the main method and exit the program.



That's exactly what is happening. Even though you might close the window, using the window icon (e.g. the red X in Windows XP), the program itself is not being told to exit. A key setting is missing. In your setUpGui method, add the following line. It doesn't matter where, but typically it is set prior to calling the setVisible(true) method.



That tells the JFrame that when the user clicks the close window icon, you want the program to exit. Without that, the program just continues to run, but nothing is visible (as you have discovered). As is states in the general class information of the Javadoc for JFrame (emphasis added):


Unlike a Frame, a JFrame has some notion of how to respond when the user attempts to close the window. The default behavior is to simply hide the JFrame when the user closes the window. To change the default behavior, you invoke the method setDefaultCloseOperation(int). To make the JFrame behave the same as a Frame instance, use setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE).



The reason this needs to be set is that sometimes you use a JFrame for windows other than the main application window. And in that case you don't want the program to exit. More info, including other possible values, is available in the Javadoc for the setDefaultCloseOperation(int operation) method itself.


It's interesting that that is missing from the example code.
[ August 04, 2008: Message edited by: Mark Vedder ]
 
Donald Hume
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ya know what! I actually tried that but stuck it in up top when JFrame j = new JFrame() was first called. Thanks a lot for the placement.

but... I've had this problem on other classes as well -- ones that didn't have a gui such as below:



What then?
 
Mark Vedder
Ranch Hand
Posts: 624
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
FYI, I did look at the errata page for the book, and this error is notated on the Unconfirmed error reports and comments from readers page. Given the nature of the beast, it is not uncommon for tech books to have some errors (and unfortunately, given the unusual editing process needed to achieve the look & feel in the Head First books, this is especially true in the Head First series. So it's always useful when getting a book, to check the book's errata page (usually found on the publisher's website, but some books have dedicated pages which are mentioned in the preface). If it is a fairly recent published book, you'll want to check the page often while the initial errors are flushed out. Hope that helps.
 
Donald Hume
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow thanks I had no clue about the corrections. Much appreciate
 
Mark Vedder
Ranch Hand
Posts: 624
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Donald Hume:
Ya know what! I actually tried that but stuck it in up top when JFrame j = new JFrame() was first called. Thanks a lot for the placement.



Yup, you can't do it in the variable declaration.

Originally posted by Donald Hume:

but... I've had this problem on other classes as well -- ones that didn't have a gui such as below:

. . .

What then?



This one's a little different. In this case, the sequence is running in a different thread. If we place some additional System.out statements in the code -- before and after calling the go() method, and before and after the calling the sequencer.start() method -- we can see what is happening:


When we run the code, we get the output:



This shows that both the go and start method return, but stuff is still happening. In other words, the sequencer is running is a separate thread. (I'm not sure if you have gotten to Threads yet; I can't remember if they are before or after where you are in the book.)

I'm not very familiar with the Sequencer class since I've never really used it. But a quick look shows there is a isRunning() method that tells us if the sequencer is still running. I was looking to see if there a method that blocks (that is waits until something is finished running), but I didn't see one. So what we can do is this:


Now when we run, the output is:



Notice the "After go" never prints. More on that in a moment. The reason we use the Thread.sleep(500) is because just doing:



would cause a very tight running loop, which will spike the CPU. As an alternative to Thread.sleep(), if you are using Java 5 or later, you can use
TimeUnit.SECONDS.sleep(1) to sleep for a second, or TimeUnit.MILLISECONDS.sleep(500) for a 1/2 second, or any variation. I personally find the TimeUnit.XYZ.sleep() methods clearer, especially when sleeping for long times.

Now back to the "After Go" not printing. In the current form we are exiting the code in an unusual place... in the middle of the go() method. This makes the code hard to follow and trace, and potentially error prone. So what we can do is this. Make the Sequencer an instance variable (a.k.a a field) and then either put the code that waits for the sequencer to finish in the main method, or in a separate method that is called in the main method. The second option is a bit cleaner looking. So we end up with:



And when run, we get:



This way the code exits nicely from the main method.

Of course, you can then remove the System.out statements. Later in your programming experience, you'll learn about logging frameworks and how they can be used to turn such debugging output on and off very easily. But for now you can use System.out.

I hope that helps.
[ August 04, 2008: Message edited by: Mark Vedder ]
 
Mark Vedder
Ranch Hand
Posts: 624
IntelliJ IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
p.s. in case it's not clear what this code is doing:


it keeps looping through until the sequencer is no longer running. It pauses for 1/2 second (500 milliseconds) between checks.
[ August 04, 2008: Message edited by: Mark Vedder ]
 
Donald Hume
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow, Mark Vedder thank you so much. Not only was your explanation crystal clear but it prompted me to rebuild and earlier class file that was having the same problem to make sure I grasped the concept.

Much appreciated. Snaps for you *snap snap*

(:
 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello,
I just read this section of the book too. It looks like the proper way to listen for the end of the track is to register a metaEventListener with an anonymous callback.
Add this after


The compiler will complain about a "local variable 'player' is accessed from within inner class...' Mark the variable as final to fix this error.

This method is more elegant than the sleep method b/c it tells you EXACTLY when the track ends. BTW, 47 is the code for the end of track event.
 
Marshal
Posts: 79153
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch and thank you for a useful addition
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic