Chord.setOctave(x) returns 注释在 jFugue 5 中有错误的值。我错过了什么?
Chord.setOctave(x) returns notes with wrong value in jFugue 5. what am I missing?
示例代码如下:
public class TestNoteValue {
public static void main(String[] args) {
Chord c = new Chord("C5maj");
DevLog.debug(MusicAnnotationUtil.reportChord(c));
// ----------------
c.setOctave(4);
DevLog.debug(MusicAnnotationUtil.reportChord(c));
}
}
结果输出:
第一次结果正确:
和弦{Note{C5, 60}, Note{E5, 64}, Note{G5, 67}, }
C5的值确实是60。
但是在 Chord.setOctave(4) 之后,它并没有改变第一个音符的表达式,而是改变了它的值。导致正确性受损的注释数组:
和弦{音符{C5, 48}, 音符{E4, 52}, 音符{G4, 55}, }
我是不是遗漏了什么?
感谢您的帮助!
由于 David 正在帮助查看代码,我将 post 我的临时解决方法。希望对其他人有帮助。
public static Chord setOctave(Chord c, byte octave) {
DevLog.super_trace("setting octave for chord "+c+" to "+octave);
c.setOctave(octave);
Note[] nA = new Note[3];
for(int i=0; i<c.getNotes().length; i++){
nA[i] = new Note(c.getNotes()[i].getValue());
}
return Chord.fromNotes(nA);
}
我在注释 class 中添加了一个新方法,它会更新 "original string",当注释的值发生更改时,便会使用该方法创建注释。
我会在解决一些其他问题后发布一个新版本。与此同时,以下是 Note.java 中发生的变化:
更新方法:
public Note setValue(byte value) {
this.value = value;
this.updateOriginalString(); // New line that calls the method below
return this;
}
新方法:
private void updateOriginalString() {
if (this.getOriginalString() != null) {
String oldOriginalString = this.getOriginalString();
StringBuilder newOriginalString = new StringBuilder();
newOriginalString.append(getToneString());
if ((oldOriginalString.length() > 1) && (oldOriginalString.substring(oldOriginalString.length()-2, oldOriginalString.length()-1).matches("\d"))) {
newOriginalString.append(getOctave());
}
setOriginalString(newOriginalString.toString());
}
}
以及 NoteTest.java 中的新测试:
@Test
public void testOriginalStringForNotes() {
assertTrue(new Note("C").getOriginalString().equals("C"));
assertTrue(new Note("C5").getOriginalString().equals("C5"));
assertTrue(new Note("C").changeValue(+1).getOriginalString().equals("C#"));
assertTrue(new Note("C5").changeValue(+1).getOriginalString().equals("C#5"));
assertTrue(new Note("C").setValue((byte)48).getOriginalString().equals("C"));
assertTrue(new Note("C5").setValue((byte)48).getOriginalString().equals("C4"));
}
示例代码如下:
public class TestNoteValue {
public static void main(String[] args) {
Chord c = new Chord("C5maj");
DevLog.debug(MusicAnnotationUtil.reportChord(c));
// ----------------
c.setOctave(4);
DevLog.debug(MusicAnnotationUtil.reportChord(c));
}
}
结果输出:
第一次结果正确: 和弦{Note{C5, 60}, Note{E5, 64}, Note{G5, 67}, }
C5的值确实是60。 但是在 Chord.setOctave(4) 之后,它并没有改变第一个音符的表达式,而是改变了它的值。导致正确性受损的注释数组: 和弦{音符{C5, 48}, 音符{E4, 52}, 音符{G4, 55}, }
我是不是遗漏了什么?
感谢您的帮助!
由于 David 正在帮助查看代码,我将 post 我的临时解决方法。希望对其他人有帮助。
public static Chord setOctave(Chord c, byte octave) {
DevLog.super_trace("setting octave for chord "+c+" to "+octave);
c.setOctave(octave);
Note[] nA = new Note[3];
for(int i=0; i<c.getNotes().length; i++){
nA[i] = new Note(c.getNotes()[i].getValue());
}
return Chord.fromNotes(nA);
}
我在注释 class 中添加了一个新方法,它会更新 "original string",当注释的值发生更改时,便会使用该方法创建注释。
我会在解决一些其他问题后发布一个新版本。与此同时,以下是 Note.java 中发生的变化:
更新方法:
public Note setValue(byte value) {
this.value = value;
this.updateOriginalString(); // New line that calls the method below
return this;
}
新方法:
private void updateOriginalString() {
if (this.getOriginalString() != null) {
String oldOriginalString = this.getOriginalString();
StringBuilder newOriginalString = new StringBuilder();
newOriginalString.append(getToneString());
if ((oldOriginalString.length() > 1) && (oldOriginalString.substring(oldOriginalString.length()-2, oldOriginalString.length()-1).matches("\d"))) {
newOriginalString.append(getOctave());
}
setOriginalString(newOriginalString.toString());
}
}
以及 NoteTest.java 中的新测试:
@Test
public void testOriginalStringForNotes() {
assertTrue(new Note("C").getOriginalString().equals("C"));
assertTrue(new Note("C5").getOriginalString().equals("C5"));
assertTrue(new Note("C").changeValue(+1).getOriginalString().equals("C#"));
assertTrue(new Note("C5").changeValue(+1).getOriginalString().equals("C#5"));
assertTrue(new Note("C").setValue((byte)48).getOriginalString().equals("C"));
assertTrue(new Note("C5").setValue((byte)48).getOriginalString().equals("C4"));
}