首创设计模式 - 组合模式

时间:2011-07-01 03:37:46

标签: java design-patterns

我正在阅读关于头部优先设计模式中的组合模式的第12章。 在页541,示例DJView,它无法在我的电脑中正确运行。当我按下'开始'时,程序只发出一次而不是循环播放。 我不确定是否因为我的系统环境。 但如果我在 BeatModel 类的方法 meta 中添加一行代码,它就可以工作。

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

谁能告诉我为什么?我很困惑,这本书给出的代码有什么问题或其他原因?帮我 。 提前谢谢!!
很抱歉,代码很长,所以我无法全部放在这里,您可以从官方网站下载,这里是链接 http://www.headfirstlabs.com/books/hfdp/HeadFirstDesignPatterns_code102507.zip
你可以在这个文件夹'\ HeadFirstDesignPatterns_code102507 \ HF_DP \ src \ headfirst \ combined \ djview'中找到样本。
运行课程 DJTestDrive.java
 期待您的帮助。

3 个答案:

答案 0 :(得分:3)

编辑#2 :为了完整起见,Head First Design Patterns的作者Elisabeth Freeman本人已经注意到她的书中的代码仅使用Java 1.4进行了测试。她承诺会考虑我们的反馈意见。


编辑:播放期间Sequencer.setTempoInBPM似乎存在错误。将微秒位置设置为0的方法是正确的方法 - 它基本上会在序列结束时将其重新排序(即消息类型= 47)。


不幸的是,示例代码似乎不正确。有几个问题:

  1. sequencer未初始化为循环播放
  2. meta()方法重置BPM并重新通知所有侦听器,但不会将音序器重置到其原始位置,您可以将其重置为原始位置。但是,只要将音序器设置为循环播放,此方法就不需要执行任何操作。
  3. off()方法将BPM设置为0,这将快速将序列发生器转发到所有循环的末尾 - 这意味着下次启动播放器时,它将从结束开始,什么都不玩。
  4. 这些改变应该可以解决问题:

    #1 在方法BeatModel.buildTrackAndStart中,按如下方式添加sequencer.setLoopCount

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

    #2 删除方法BeatModel.meta(MetaMessage)中的所有语句:

    public void meta(MetaMessage message) {
    }
    

    #3 从方法setBPM(0)移除BeatModel.off()

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

答案 1 :(得分:1)

在Java 8上添加

sequencer.setMicrosecondPosition(0);

到BeatModel.meta()使它工作正常!

向所有人致以问候, hebgeenbrug

答案 2 :(得分:0)

阅读时遇到类似的错误。在我的计算机中,processBar不会更新。

1。首先,我添加“ sequencer.setMicrosecondPosition(0);”在“ public void meta(MetaMessage message)”中;

2。第二,我删除“ sequencer.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);”在“ public void setUpMidi()”中;它会连续发出声音,但不会注意到“ meta(MetaMessage消息)”,因此ProcessBar无法更新。

3。然后它起作用

也许是我的经验可以帮助别人。