2016-01-30 81 views
0

我想應用裝飾模式,但到目前爲止我有麻煩得到它以我想要的方式工作。裝飾模式鋼琴應用程序

基本上我試圖創建一個鋼琴應用程序,它有一個鋼琴鍵超類,它擴展了JavaFX矩形和兩個子類白鍵和黑鍵,當你將鼠標懸停在它們上面時,它們都有方法的實現。

他們工作正常,但我現在試圖創建裝飾類,它將通過提供自己的播放方法併爲該裝飾器的音頻文件附加相關字​​符串來覆蓋超類的播放方法。 例如PianoKeyViolinDecorator在播放音頻文件名稱之前會將「小提琴」附加到音頻文件名的末尾。

該播放方法的作品,但方法懸停在矩形不起作用。除非在Decorator中設置高度和寬度,否則矩形將不會顯示在我的GUI中。有沒有辦法讓琴鍵的矩形顯示出來,而不必在Decorator類中重新創建一個新的矩形?

這裏是我的裝飾類:

public class PianoKeyDecorator extends KeyView { 

private KeyView keyView; 

public PianoKeyDecorator(KeyView keyView) { 
    this.keyView = keyView; 
} 

public void lightOn() { 
    keyView.lightOn(); 
} 

public void lightOff() { 
    keyView.lightOff(); 
} 

@Override 
public void play() { 
    AudioClip audioFile = new AudioClip(AssignmentTemplate.class.getResource(keyView.keyAudioSource() + "_violin.wav").toExternalForm()); 
    audioFile.play(); 
} 

而且我超類

public abstract class KeyView extends Rectangle { 

private AudioClip keyAudio; 
private String keyAudioSource; 
private String keyId; 
private String background; 
private String backgroundHover; 

public KeyView(double width, double height, String keyAudioSource, String keyText, String background, String backgroundHover) { 
    this.keyAudioSource = keyAudioSource; 
    keyAudio = new AudioClip(AssignmentTemplate.class.getResource(keyAudioSource + ".wav").toExternalForm()); 
    this.background = AssignmentTemplate.class.getResource("resources/"+ background).toExternalForm(); 
    this.backgroundHover = AssignmentTemplate.class.getResource("resources/"+ backgroundHover).toExternalForm(); 
    this.getStyleClass().add("key"); 
    setWidth(width); 
    setHeight(height); 
} 

public KeyView(){} 

public void play() { 
    keyAudio.play(); 
} 

public void setAudioClip(AudioClip keyAudio) { 
    this.keyAudio = keyAudio; 
} 

public abstract void lightOn(); 
public abstract void lightOff();  

public void setKeyId(String keyId) { 
    this.keyId = keyId; 
} 

public String getKeyId() { 
    return keyId; 
} 

public String getBackground() { 
    return background; 
} 

public String getBackgroundHover() { 
    return backgroundHover; 
} 

public String keyAudioSource() { 
    return keyAudioSource; 
} 

這是我的一個子類

公共類BlackKeyView擴展的KeyView {

public SharpKeyView(String keyAudioFile, String keyText, String background, String backgroundHover) { 
     super(64, 170, keyAudioFile, keyText, background, backgroundHover); 
     setKeyId("sharp" + keyText); 
} 

public void lightOn() { 
    super.setFill(Color.BLUE); 
} 

public void lightOff() { 
    super.setFill(Color.BLACK); 
} 

回答

1

s implest的方式很可能是你的裝飾的所有相關屬性綁定到底層對象:

public PianoKeyDecorator(KeyView keyView) { 
    this.keyView = keyView; 
    fillProperty().bindBidirectional(keyView.fillProperty()); 
    // bind any other properties you wish to change. 
} 

不同的方法可能是從他們的邏輯鑰匙的視圖部分完全分離,但大概會迫使你改變你的設計相當多。

編輯:
試想想起來了,我覺得這個例子的strategy設計模式可能適合比裝飾好多了,所以你只能改變聲音代替播放的整個鍵的方式。