Thanks for all the answers. The example is from page 342 in Head First Java (2nd edition).
_I_ haven't created a new
thread, but I'm not sure if this might be the answer to the question. I have used a text editor and Netbeans. There is no difference. The program itself runs, but it will not stop, so setting a breakpoint won't help. I found a typo in my first posting (a instead of b), but that doesn't effect the problem.
I finally found the source code for the book and in the file there are some important differences to the printed version. I have added a /////new comment in the added lines.
// --------- code begin --------------
import javax.sound.midi.*;
public class MiniMiniMusicApp { // this is the first one
public static void main(String[] args) {
MiniMiniMusicApp mini = new MiniMiniMusicApp();
mini.play();
}
public void play() {
try {
// make (and open) a sequencer, make a sequence and track
Sequencer sequencer = MidiSystem.getSequencer();
sequencer.open();
Sequence seq = new Sequence(Sequence.PPQ, 4);
Track track = seq.createTrack();
// now make two midi events (containing a midi message)
MidiEvent event = null; //////////new
// first make the message
// then stick the message into a midi event
// and add the event to the track
ShortMessage a = new ShortMessage();
a.setMessage(144, 1, 44, 100);
MidiEvent noteOn = new MidiEvent(a, 1); // <-- means at tick one, the above event happens
track.add(noteOn);
ShortMessage b = new ShortMessage();
b.setMessage(128, 1, 44, 100);
MidiEvent noteOff = new MidiEvent(b, 16); // <-- means at tick one, the above event happens
track.add(noteOff);
// add the events to the track
// add the sequence to the sequencer, set timing, and start
sequencer.setSequence(seq);
sequencer.start();
Thread.sleep(1000); /////////new
sequencer.close(); /////////new
System.exit(0); ////////new
} catch (Exception ex) {ex.printStackTrace();}
} // close play
} // close class
// --------- code end --------------
The first difference is
MideEvent event = null;
which is _not_used anywhere in the program!?
Then later
Thread.sleep(1000); /////////new
sequencer.close(); /////////new
System.exit(0); ////////new
are added.
Threads are not explained at this point in the book, but without the sleep()-method the piano tone can not always be heard when one closes the sequencer. If the sequencer is not closed the program will not terminate, neither on Windows XP nor on OS X.
After forcing the thread to sleep so the tone can be heard the sequencer is closed. I found this myself by looking in the API docs. And now comes an interesting point I found out.
sequencer.close() is sufficient for the program to stop itself when I run the program in Windows XP. But when running the program on OS X (with latest Java 5) the program will not terminate. One has to add
System.exit();
I'm somewhat confused now about the different behavior and the additional System.exit() needed on OS X.
It took me quite some time to figure these things out. That's not the real problem, but IMO this wasn't neccessary. There's an errata for the book which fixes errors, but this wrong listing is not mentioned, allthough I found two postings on the Javaranch forum which asked a similar question to mine. One was not answered at all. The other was
https://coderanch.com/t/399099/java/java/stop-music I twice e-mailed Kathy and Bert (the authors) with suggestions and questions, but got no answer :-( I hoped that a here -- the official unofficial "Head First Java" homepage -- would be a place where additions to the book could be posted or better could be organized in a Wiki. This would be greatly beneficial for the readers of the book.
If someone knows how to get through to Kathy and Bert I like to get a pointer (not a reference here ;-)
Thank you for taking the time to read and answer my post.
Greetings from germany
Peter