Head First Design Patterns – Combined Pattern

Tags: ,



I’m reading the chapter 12 on the Combined Pattern in Head First Design Patterns. On page 541,the sample DJView,it cant’t run correctly in my computer.when i press the ‘start’, the program only sounds once rather than circularly . i’m not sure whether because of the environment of my system. but if i add one line code in the method meta of the class BeatModel,it works.like:

  public void meta(MetaMessage message) {
        if (message.getType() == 47) {
            beatEvent();
            sequencer.setMicrosecondPosition(0);  //add this line
            sequencer.start();
            setBPM(getBPM());
        }
    }

can anyone tell me why? i’m so confused,is something wrong with the code given by the book or some other reason? help me . Thanks in advance!!
So sorry,the code is long so i could not put all here´╝îyou could download from the offical website,here is the link http://www.headfirstlabs.com/books/hfdp/HeadFirstDesignPatterns_code102507.zip
you can find the sample in this folder ‘HeadFirstDesignPatterns_code102507HF_DPsrcheadfirstcombineddjview’.
run the class DJTestDrive.java
Look forward to your help.

Answer

EDIT #2: For completeness’ sake, the author of Head First Design Patterns Elisabeth Freeman herself has made a note of the fact that the code in her book has only been tested with Java 1.4. She has promised to take our feedback into account.


EDIT: There seems to be a bug with the Sequencer.setTempoInBPM during play. Your approach with setting the microsecond position to 0 is the right approach — it basically rewinds the sequencer as soon as it ends (i.e. message type = 47).


Unfortunately, the sample code seems incorrect. There are several problems:

  1. The sequencer is not initialized to play in a loop
  2. The meta() method resets the BPM and renotifies all listeners, but does not reset the sequencer to its original position, which you did to get it to work. However, this method does not need to do anything so long as the sequencer is set to play in a loop.
  3. The off() method sets the BPM to 0, which will fast forwards the sequencer to the end of all loops — which means next time you start the player, it will start from the end and will play nothing.

These change should do the trick:

#1 In method BeatModel.buildTrackAndStart, add sequencer.setLoopCount as follows:

 public void buildTrackAndStart() {
    // ...
    try {
        sequencer.setSequence(sequence);
        sequencer.setLoopCount(Integer.MAX_VALUE); // play forever
    } catch(Exception e) {
    // ...
} 

#2 Remove all statements from method BeatModel.meta(MetaMessage):

public void meta(MetaMessage message) {
}

#3 Remove setBPM(0) from method BeatModel.off():

public void off() {
    // -- remove this -- setBPM(0);
    sequencer.stop();
}


Source: stackoverflow