这是接上面的,和NoteBean.java放在一起到APPLET里测试就可以看到乐谱了
DrawStaffs.java
//import notebean
import java_graphics_programming_library.NoteBean;import java.applet.*;
import java.util.Vector;
import java.awt.Graphics;
import java.awt.Color;public class DrawStaffs extends Applet{  //定义一个NoteBean[]放每个音符
  NoteBean[] notes = null;
  //myvector是测试用的vector
  Vector myvector = null;  //constructor,初始化测试vector
  public DrawStaffs() {
    myvector = new Vector();
    myvector.addElement("E");
    myvector.addElement("E");
    myvector.addElement("Ea");
    myvector.addElement("/");
    myvector.addElement("E");
    myvector.addElement("E");
    myvector.addElement("Ea");
    myvector.addElement("/");
    myvector.addElement("E");
    myvector.addElement("G");
    myvector.addElement("Ce");
    myvector.addElement("De");
    myvector.addElement("Ea");
  }//DrawStaffs()  //initialize以测试用的vec得到一个NoteBean[],然后以这个NoteBean[]为参数绘制图形
  public NoteBean[] initialize(Vector vec){
    int i;
    //这里不过是例行检查
    System.out.println(vec.size());
    //实例化一个NoteBean[]对象 notes,以vec的长度为数组长度
    notes = new NoteBean[vec.size()];
    //实例化NoteBean[]里的每个note
    for(i=0;i<notes.length;i++){
      notes[i] = new NoteBean();
    }    //用bean的setNote和setTime方法实例每个bean的note(音符)和time(节拍)
    for(i=0;i<vec.size();i++){
      notes[i].setNote(String.valueOf(vec.elementAt(i)));
      notes[i].setTime(String.valueOf(vec.elementAt(i)));
      //这里还是例行检查
      System.out.println(notes[i].getNote());
    }    return notes;
  }//initialize(Vector vec)  //paintnotes以NoteBean[]为参数绘制乐谱
  public void paintnotes(Graphics gc,NoteBean[] n){    //offstaff是音符的其始位置
    int offstaff = 50;
    //basePointX和basePointY是整个乐谱的基点
    int basePointX = 0;
    int basePointY = 0;
    //组成音符的圆的直径
    int radius = 10;
    //组成音符的茎的长度
    int length = 17;    //下面开始正式绘制音符
    for(int i=0;i<n.length;i++){
      int offnote = n[i].getNote();
      int offtime = n[i].getTime();
      //0代表是"/"
      if(offnote == 0){
        gc.drawLine(offstaff,50,offstaff,90);
        offstaff+=10;
      }
      else{
        basePointX = offstaff;
        basePointY = 70+offnote*5;        //1/4拍
        if(offtime == 1&&offnote!=0){
          gc.fillOval(basePointX,basePointY,radius,radius);
          gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
        }
        //2/4拍
        if(offtime == 2){
          gc.drawOval(basePointX,basePointY,radius,radius);
          gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
        }
        //3/4拍
        if(offtime == 3){
          //我不知道3/4拍怎么画,放着再说
          //as additional feature in future version
        }
        //全音符
        if(offtime == 4){
          gc.drawOval(basePointX,basePointY,radius,radius);
        }
        //1/8拍
        if(offtime == 8){
          gc.fillOval(basePointX,basePointY,radius,radius);
          gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
          gc.drawLine(basePointX+radius,basePointY-length,basePointX+radius+5,basePointY-length+3);
        }
        //1/16拍
        if(offtime == 16){
          //as additional feature in future version
        }
        offstaff+=20;
      }
    }
  }//paintnotes(Graphics gc,NoteBean[] n)  //这里绘制五线谱
  public void paintstaff(Graphics gc){
    gc.drawLine(0,50,500,50);
    gc.drawLine(0,60,500,60);
    gc.drawLine(0,70,500,70);
    gc.drawLine(0,80,500,80);
    gc.drawLine(0,90,500,90);
  }//paintstaff(Graphics gc)  //Applet的paint()
  public void paint(Graphics gc){
    NoteBean[] n = initialize(myvector);
    paintstaff(gc);
    paintnotes(gc,n);
  }//paint(Graphics gc)
}//class DrawStaffs

解决方案 »

  1.   

    整和前的就是这样,今天早上把两部分整和时,出现无限循环,代码如下:
    把下面这个和NoteBean.java放在一起就可以了,我不过是把testReadEnter.java里的main函数放到DrawStaffs.java里去了,另外增加了处理不止一行五线谱的情况,就是这里因为没有把五线谱类抽象出来,所以处理起来比较麻烦。
    package java_graphics_programming_library;//import notebean
    import java_graphics_programming_library.NoteBean;import java.applet.*;
    import java.util.Vector;
    import java.awt.Graphics;
    import java.awt.Color;
    import java.io.*;
    import java.util.StringTokenizer;public class DrawStaffs extends Applet{  private String          FileURL         = null;
      private FileInputStream fileinputstream = null;
      private DataInputStream datainputstream = null;
      private Vector          indexofenter    = new Vector();
      private int             NumEnter        = 0;
      private int             NumRow          = 0;
      private String[]        RowNotes;
      public  Vector[]        staffs;
      //定义一个NoteBean[]放每个音符
      NoteBean[] notes = null;
      //myvector是测试用的vector
      Vector myvector = null;  //constructor,初始化测试vector
      public DrawStaffs() {
        myvector = new Vector();
        myvector.addElement("E");
        myvector.addElement("E");
        myvector.addElement("Ea");
        myvector.addElement("/");
        myvector.addElement("E");
        myvector.addElement("E");
        myvector.addElement("Ea");
        myvector.addElement("/");
        myvector.addElement("E");
        myvector.addElement("G");
        myvector.addElement("Ce");
        myvector.addElement("De");
        myvector.addElement("Ea");
      }//DrawStaffs()  //initialize以测试用的vec得到一个NoteBean[],然后以这个NoteBean[]为参数绘制图形
      public NoteBean[] initialize(Vector vec){
        int i;
        //这里不过是例行检查
        //System.out.println(vec.size());
        //实例化一个NoteBean[]对象 notes,以vec的长度为数组长度
        notes = new NoteBean[vec.size()];
        //实例化NoteBean[]里的每个note
        for(i=0;i<notes.length;i++){
          notes[i] = new NoteBean();
        }    //用bean的setNote和setTime方法实例每个bean的note(音符)和time(节拍)
        for(i=0;i<vec.size();i++){
          notes[i].setNote(String.valueOf(vec.elementAt(i)));
          notes[i].setTime(String.valueOf(vec.elementAt(i)));
        }    return notes;
      }//initialize(Vector vec)  //paintnotes以NoteBean[]为参数绘制乐谱
      public void paintnotes(Graphics gc,NoteBean[] n,int num){    int staffbegset = 50;
        int staffendset = 0;
        int staffdistance = 30;
        //offstaff是音符的其始位置
        int offstaff = 50;
        //basePointX和basePointY是整个乐谱的基点
        int basePointX = 0;
        int basePointY = 0;
        //组成音符的圆的直径
        int radius = 10;
        //组成音符的茎的长度
        int length = 17;    //下面开始正式绘制音符
        for(int i=0;i<n.length;i++){
          int offnote = n[i].getNote();
          int offtime = n[i].getTime();
          //0代表是"/"
          if(offnote == 0){
            gc.drawLine(offstaff,50+num*30,offstaff,90+num*30);
            offstaff+=10;
          }
          else{
            basePointX = offstaff;
            basePointY = 70+offnote*5+num*30;        //1/4拍
            if(offtime == 1&&offnote!=0){
              gc.fillOval(basePointX,basePointY,radius,radius);
              gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
            }
            //2/4拍
            if(offtime == 2){
              gc.drawOval(basePointX,basePointY,radius,radius);
              gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
            }
            //3/4拍
            if(offtime == 3){
              //我不知道3/4拍怎么画,放着再说
              //as additional feature in future version
            }
            //全音符
            if(offtime == 4){
              gc.drawOval(basePointX,basePointY,radius,radius);
            }
            //1/8拍
            if(offtime == 8){
              gc.fillOval(basePointX,basePointY,radius,radius);
              gc.drawLine(basePointX+radius,basePointY+radius/2,basePointX+radius,basePointY-length);
              gc.drawLine(basePointX+radius,basePointY-length,basePointX+radius+5,basePointY-length+3);
            }
            //1/16拍
            if(offtime == 16){
              //as additional feature in future version
            }
            offstaff+=20;
          }
        }
      }//paintnotes(Graphics gc,NoteBean[] n)  //只要把这个main()改成return staff的函数就可以用了
      public Vector[] NoteReader(){
          //stmstr是放置文本内容的string
          String stmstr    = new String();
          byte[] data      = new byte[1];
          int nbyteread;
          FileURL          = "Test.txt";
          Vector staff     = new Vector();
        try{
          //读入Test.txt文件,写到stmstr中
          fileinputstream  = new FileInputStream(FileURL);
          datainputstream  = new DataInputStream(fileinputstream);
          while((nbyteread = datainputstream.read(data)) != -1){
            stmstr = stmstr + new String(data,0,nbyteread);
          }
          datainputstream.close();
          fileinputstream.close();
        }catch(IOException ioe){
          System.err.println(ioe.getMessage());
        }    /*
        //这里是我原来的得到文本中每行的方法,笨方法,后面用正则表达式就简单多了,但这里我懒得改了
        int IndexOfEnter = 0;
        System.out.println(stmstr.length());
        while(IndexOfEnter < stmstr.length()){
          IndexOfEnter = stmstr.indexOf("\r\n",IndexOfEnter);
          if(IndexOfEnter != -1){
            indexofenter.addElement(new Integer(IndexOfEnter));
            System.out.println(IndexOfEnter);
            NumEnter++;
            IndexOfEnter++;
          }else{
            break ;
          }
        }    System.out.println("the index of Enter :");
        for(int i=0;i<indexofenter.size();i++){
          System.out.print(indexofenter.elementAt(i)+" ");
        }
        System.out.println();
        System.out.println("the number of Enter : "+NumEnter);
        */    //这里用jdk1.4的StringTokenizer类就方便多了,处理流的专用类,和正则表达式联合起来更强大
        StringTokenizer st = new StringTokenizer(stmstr,"\r\n",false);
        NumRow = st.countTokens();
        RowNotes = new String[NumRow];
        for(int i=0;i<NumRow;i++){
          RowNotes[i] = st.nextToken();
        }
        System.out.println(RowNotes[0]);
        System.out.println(RowNotes[1]);
        System.out.println(RowNotes[2]);
        System.out.println(RowNotes[3]);
        System.out.println(RowNotes[4]);
        System.out.println(RowNotes[5]);
        System.out.println(RowNotes[6]);    staffs = new Vector[NumRow-3];
        for(int j=0;j<staffs.length;j++){
          staffs[j] = new Vector();
        }
        for(int i=3;i<NumRow;i++){
          String tempstr = RowNotes[i].replaceAll("/"," / ");
          StringTokenizer staffToken = new StringTokenizer(tempstr," ",false);
          System.out.print(staffToken.countTokens());  //就是这里,无限循环,不知道为什么    //把每个token放到staff中去,只要返回这个staff就ok了
          for(i=0;i<staffs.length;i++){
            while(staffToken.hasMoreElements()){
              staffs[i].addElement(staffToken.nextToken());
            }
          }
        }    return staffs;
      }  //这里绘制五线谱
      public void paintstaff(Graphics gc,int i){
        int staffbegset = 50;
        int staffendset = 0;
        int staffdistance = 30;
        gc.drawLine(0,staffbegset+i*30,500,staffbegset+i*30);
        gc.drawLine(0,staffbegset+i*30+10,500,staffbegset+i*30+10);
        gc.drawLine(0,staffbegset+i*30+20,500,staffbegset+i*30+20);
        gc.drawLine(0,staffbegset+i*30+30,500,staffbegset+i*30+30);
        gc.drawLine(0,staffbegset+i*30+40,500,staffbegset+i*30+40);
      }//paintstaff(Graphics gc)  //Applet的paint()
      public void paint(Graphics gc){
        Vector[] mystaffs = NoteReader();    for(int i=0;i<mystaffs.length;i++){
          paintstaff(gc,i);
          NoteBean[] n = initialize(mystaffs[i]);
          paintnotes(gc,n,i);
        }
        //paintnotes(gc,n);
      }//paint(Graphics gc)
    }//class DrawStaffs
      

  2.   

    谢谢楼上帮我UP,不过各位也可以试试我的那个APPLET运行的,看看我画的五线谱如何啊?5555555
      

  3.   

    hoho,解决了,某某某,分给你啦!