本人比较菜,按书上的象棋打谱系统的源码进行了一些个性化的修改,但是发现一个非常严重的问题,在ChessBord类里面定义paintcomponent 函数的时候如果使用 g.drawImage 然后保存,整个类里面的部分信息丢失,用g.fillRect 却完全不会,我很费解, 希望有能力的同学帮我看看现在贴出 重点的类和函数ChinaChess 类里面主要是点击了saveMenul 按钮对 board 对象进行保存, 代码如下public class ChinaChess extends JFrame implements ActionListener{    
ChessBoard board;                                    
    DemoManulDialog demoManul;                      
    JMenuBar bar;                                           
    JMenu makeMenu,showMenu,set,music,hf,player;                       
  JMenuItem  makeShiZhanManul,makeCanJuManul,openManulAndShow,dkbf; 
                       makeShiZhanManul,makeCanJuManul,openManulAndShow
    JButton startMakeManul,saveManul;            
    JTextField hintMessage;                               
    JRadioButtonMenuItem  on,off;             
    JRadioButtonMenuItem n1,n2,n3,n4;      
    static int a=1;
    
    
    MusicPlayer mu;
 
    
    public ChinaChess(){                 
    
    
        setTitle("中国象棋棋谱制作系统");  
        mu=new MusicPlayer("音乐播放器");
        mu.setVisible(false);
        
        board=new ChessBoard();           
       board.setOpen(true);           
             add(board,BorderLayout.CENTER);     
        bar=new JMenuBar();                    
        makeMenu=new JMenu("选择制作棋谱的方式"); 
        showMenu=new JMenu("棋谱");                            
        set=new JMenu("设置");                
        music=new JMenu("音效");        
        
        dkbf=new JMenuItem("打开播放器");
        dkbf.addActionListener(this);
        
        player=new JMenu("音乐播放器");
        
        hf=new JMenu("更换背景");
        
        ButtonGroup group1=new ButtonGroup();              
        ButtonGroup group2=new ButtonGroup();   
        
        n1=new JRadioButtonMenuItem("粉红");
        n2=new JRadioButtonMenuItem("黄");
        n3=new JRadioButtonMenuItem("蓝");
        n4=new JRadioButtonMenuItem("绿");
        
        
        on=new JRadioButtonMenuItem("打开声音");           
        off=new JRadioButtonMenuItem("关闭声音"); //初始化一个名为;关闭声音的单选项
        on.addActionListener(this);        //为单选项on添加监听器
        off.addActionListener(this);      //为单选项off添加监听器
        
        n1.addActionListener(this);
        n2.addActionListener(this);
        n3.addActionListener(this);
        n4.addActionListener(this);
        
        group1.add(on);             
        group1.add(off);                     
        
        
        group2.add(n1);
        group2.add(n2);
        group2.add(n3);
        group2.add(n4);       
        n1.setSelected(true);       
        on.setSelected(true);             
        music.add(on);
        music.add(off);
        hf.add(n1);
        hf.add(n2);
        hf.add(n3);
        hf.add(n4);
        
        set.add(hf);
        set.add(music);
        player.add(dkbf);
        makeShiZhanManul=new JMenuItem("制作实战棋谱");   
        makeCanJuManul=new JMenuItem("制作残局棋谱");    
        openManulAndShow=new JMenuItem("打开一个棋谱并演示");
        makeMenu.add(makeShiZhanManul);      
        makeMenu.add(makeCanJuManul);      
        showMenu.add(openManulAndShow);      
        bar.add(makeMenu);                      
        bar.add(showMenu);                    
        bar.add(set);     
        bar.add(player);        setJMenuBar(bar);                         
        makeShiZhanManul.addActionListener(this); 
        makeCanJuManul.addActionListener(this); 
        openManulAndShow.addActionListener(this); 
        startMakeManul=new JButton("开始制作棋谱"); 
        startMakeManul.setVisible(false);     //设置startMakeManul一开始为不可见
        startMakeManul.addActionListener(this);
        saveManul=new JButton("保存棋谱");     //初始化saveManul按钮,并且设置文本为"保存棋谱"
        saveManul.setVisible(false);          //设置saveManul一开始为不可见
        saveManul.addActionListener(this);   
        hintMessage=new JTextField(30);       //初始化hintMessage,并且设置大小为30个字符
        hintMessage.setHorizontalAlignment(JTextField.CENTER);     //设置hintMessage为居中
        hintMessage.setFont(new Font("细黑",Font.PLAIN,15));      //设置hintMessage的提示语句的字体为细黑,大小为15
        hintMessage.setEditable(false);      //设置hintMessage为不可编辑
        hintMessage.setText("请单击菜单,选择制作棋谱的方式或演示已有的棋谱");  //设置hintMessage的默认文本为“请单击菜单,选择制作棋谱的方式或演示已有的棋谱”
        hintMessage.setBackground(Color.green);      //设置背景颜色为绿色
        JPanel north=new JPanel();   //创建面板对象north
        north.add(hintMessage);      //把hintMessage添加到面板对象north中
        north.add(startMakeManul);    //把startMakeManul添加到面板对象north中
        north.add(saveManul);        //把saveManul添加到面板对象north中
        add(north,BorderLayout.NORTH);  
        setVisible(true);           //设置为可见
        setBounds(120,10,710,580);      //设置框的大小以及位置
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//为框添加关闭函数
        validate();
        JOptionPane.showMessageDialog(this,
                      "请单击菜单,选择制作棋谱的方式或演示已有的棋谱","提示对话框",
                       JOptionPane.WARNING_MESSAGE);
     
   }
   public void actionPerformed(ActionEvent e){
       String message="单击\"开始制作棋谱\",然后拖动棋子走棋";
       if(e.getSource()==makeShiZhanManul) {
          board.setShizhanPlay();
          hintMessage.setText(message);
          startMakeManul.setVisible(true);
          saveManul.setVisible(false);
          JOptionPane.showMessageDialog(this,message,"提示对话框",                                                           JOptionPane.WARNING_MESSAGE);
       }   
       if(e.getSource()==makeCanJuManul){
          message="将棋盒中棋子拖入棋盘摆好残局,然后单击\"开始制作棋谱\"";
          hintMessage.setText(message);
          board.setCanjuPlay(); 
          startMakeManul.setVisible(true);
          saveManul.setVisible(false);
          JOptionPane.showMessageDialog(this,message,"提示对话框",                                                           JOptionPane.WARNING_MESSAGE);
       } 
       if(e.getSource()==startMakeManul){
          board.startMakeManul();
          hintMessage.setText("单击\"保存棋谱\"按钮可以保存棋谱");
          saveManul.setVisible(true);
          startMakeManul.setVisible(false);
       } 
       if(e.getSource()==saveManul){
           startMakeManul.setVisible(false);
           JFileChooser chooser=new JFileChooser();
           int state=chooser.showSaveDialog(null);
           File file=chooser.getSelectedFile();
           if(file!=null&&state==JFileChooser.APPROVE_OPTION){
             try{ 
                  FileOutputStream out=new FileOutputStream(file);
                  ObjectOutputStream objectOut=new ObjectOutputStream(out);
                  objectOut.writeObject(board); 
                  out.close(); 
                  objectOut.close(); 
            }
            catch(Exception event){}
           } 
       } 
       if(e.getSource()==openManulAndShow){
           JFileChooser chooser=new JFileChooser();
           int state=chooser.showOpenDialog(null);
           File file=chooser.getSelectedFile();
           if(file!=null&&state==JFileChooser.APPROVE_OPTION){
              demoManul=new DemoManulDialog(file);
              demoManul.setVisible(true);
           }
       }
    
      if(e.getSource()==on){board.setOpen(true);}//如果选择了打开音乐选项,把setOpen设为true      
       if(e.getSource()==off){board.setOpen(false);}//如果选择了关闭音乐选项,把setOpen设置为false
       if(e.getSource()==n1){a=1;}
       if(e.getSource()==n2){a=2;}
       if(e.getSource()==n3){a=3;}
       if(e.getSource()==n4){a=4;}      
       if(e.getSource()==dkbf){mu.setVisible(true);}
    
   }
   public static void main(String args[]){
       new ChinaChess();
   }
}

解决方案 »

  1.   

    第二个为ChessBoard类, 主要调用paintComponent 函数, 类代码如下
    public class ChessBoard extends JLayeredPane implements ActionListener{
         int m=10,n=9,distance=42;  
    // Toolkit toolkit;
              //Image img;  
         Point [][] playPoint;
         String [] redName={"帅","士","士","相","相","马","马","车","车","炮","炮", "兵","兵","兵","兵","兵"};
         String [] blackName={"将","仕","仕","象","象","馬","馬","車","車","炮","炮",
                             "卒","卒","卒","卒","卒"};      
         ChessPiece [] redPiece;
         ChessPiece [] blackPiece;
         ChessBox redChessBox,blackChessBox;
         InitPieceLocation initPieceLocation;
         InitCanju initCanju;
         HandleMouse handleMouse;
         ArrayList<Point> step;
         JButton cancel;  
         public ChessBoard(){//ChessBoard构造函数
              setLayout(null); //设置此容器的布局管理器
              step=new ArrayList<Point>();//建立一个ArrayList表记录对弈时棋子所走过棋点
              initPointAndPiece();  //完成棋子和棋点对象的初始化
              redChessBox=new ChessBox(distance,11,7);
              blackChessBox=new ChessBox(distance,11,1);
              for(int i=0;i<redPiece.length;i++) 
                  redChessBox.putPieceToBox(redPiece[i]);
              for(int i=0;i<blackPiece.length;i++) 
                  blackChessBox.putPieceToBox(blackPiece[i]);  
              initPieceLocation=new InitPieceLocation();
              initPieceLocation.setPoint(playPoint);
              initPieceLocation.setRedChessPiece(redPiece);
              initPieceLocation.setBlackChessPiece(blackPiece);
              initPieceLocation.setRedChessBox(redChessBox);
              initPieceLocation.setBlackChessBox(blackChessBox);
              initCanju=new InitCanju();
              initCanju.setPoint(playPoint);
              initCanju.setRedChessBox(redChessBox);
              initCanju.setBlackChessBox(blackChessBox);
           
        initCanju.setrule();//调用initCanju中的函数setrule()
              handleMouse=new HandleMouse();
              handleMouse.setStep(step);
              handleMouse.setPoint(playPoint);
              handleMouse.setRedChessBox(redChessBox);
              handleMouse.setBlackChessBox(blackChessBox);
              handleMouse.initStep();          // toolkit=getToolkit();//返回此框架的工具包。
     // img=toolkit.getImage("photo/1.jpg");//获取图片的相对路径
              cancel=new JButton("悔棋");
              add(cancel);
              cancel.setVisible(false);
              cancel.setSize(60,30);
              cancel.setLocation(13*distance,(int)(5*distance));
              cancel.addActionListener(this); 
         }
              
         
      
                public void startMakeManul(){
            cancel.setVisible(true);
            handleMouse.setRedFirstMove(true);
            handleMouse.initStep();
            for(int i=0;i<redPiece.length;i++){
                 MouseListener [] listener=redPiece[i].getMouseListeners();
                 for(int k=0;k<listener.length;k++)
                    redPiece[i].removeMouseListener(listener[k]);
                 listener=blackPiece[i].getMouseListeners();
                 for(int k=0;k<listener.length;k++)
                    blackPiece[i].removeMouseListener(listener[k]);
                 MouseMotionListener [] mr=redPiece[i].getMouseMotionListeners();
                 for(int k=0;k<mr.length;k++)
                    redPiece[i].removeMouseMotionListener(mr[k]);
                 mr=blackPiece[i].getMouseMotionListeners();
                 for(int k=0;k<mr.length;k++)
                    blackPiece[i].removeMouseMotionListener(mr[k]);
                 redPiece[i].addMouseListener(handleMouse);
                 blackPiece[i].addMouseListener(handleMouse);
                 redPiece[i].addMouseMotionListener(handleMouse);
                 blackPiece[i].addMouseMotionListener(handleMouse);
             } 
         }
         public void paintComponent(Graphics g){//绘制出棋盘上的横线、竖线和其他必要的图形
            super.paintComponent(g);
            // g.setColor(Color.blue);    //将背景色设置为绿色
           //  g.fillRect(0,0,this.getBounds().width,this.getBounds().height);        //代码出错于此,img是Image的一个类,用toolkit来获取的
            
            
        //g.drawImage(img,0,0,this.getBounds().width,this.getBounds().height,this);
             if(ChinaChess.a==1){ g.setColor(Color.pink);   }
             
             else if(ChinaChess.a==2){g.setColor(Color.yellow); g.fillRect(0,0,this.getBounds().width,this.getBounds().height);repaint(); }
             else if(ChinaChess.a==3){ g.setColor(Color.blue); repaint();  }
             else { g.setColor(Color.green); repaint();}
             g.fillRect(0,0,this.getBounds().width,this.getBounds().height);
             
           
             
            g.setColor(Color.orange);      
            g.fillRect(playPoint[0][0].x,playPoint[0][0].y,8*distance,9*distance);
            g.setColor(Color.black);//将棋盘的线设置为黑色
            for(int i=0;i<=m-1;i++){   
              g.drawLine(playPoint[i][0].x,playPoint[i][0].y,
                         playPoint[i][n-1].x,playPoint[i][n-1].y); 
            }
            for(int j=0;j<=n-1;j++){ 
              if(j>0&&j<n-1){  
               g.drawLine(playPoint[0][j].x,playPoint[0][j].y,
               playPoint[4][j].x,playPoint[4][j].y);
               g.drawLine(playPoint[5][j].x,playPoint[5][j].y,
               playPoint[m-1][j].x,playPoint[m-1][j].y); 
              } 
              else{
               g.drawLine(playPoint[0][j].x,playPoint[0][j].y,
               playPoint[m-1][j].x,playPoint[m-1][j].y);
              }
            }
            g.drawLine(playPoint[0][3].x,playPoint[0][3].y,
                       playPoint[2][5].x,playPoint[2][5].y);
            g.drawLine(playPoint[0][5].x,playPoint[0][5].y,
                       playPoint[2][3].x,playPoint[2][3].y);
            g.drawLine(playPoint[7][3].x,playPoint[7][3].y,
                       playPoint[m-1][5].x,playPoint[m-1][5].y);
            g.drawLine(playPoint[7][5].x,playPoint[7][5].y,
                       playPoint[m-1][3].x,playPoint[m-1][3].y);
            g.setFont(new Font("宋体",Font.BOLD,18));
            int w=blackPiece[0].getBounds().width;
            int h=blackPiece[0].getBounds().height; 
            Point [] boxPoint=blackChessBox.getBoxPoint(); 
            g.drawString("黑棋盒",boxPoint[5].getX(),boxPoint[5].getY());
            g.drawRect(boxPoint[0].getX()-w/2-2,boxPoint[0].getY()-2*h/3,
                       4*distance+5,4*distance+8);  
            g.setColor(Color.red);
            boxPoint=redChessBox.getBoxPoint();
            w=redPiece[0].getBounds().width;
            h=redPiece[0].getBounds().height;
            g.drawString("红棋盒",boxPoint[5].getX(),boxPoint[5].getY());
            g.drawRect(boxPoint[0].getX()-w/2-2,boxPoint[0].getY()-2*h/3,
                       4*distance+5,4*distance+8);
            g.setColor(Color.black);
            for(int j=1;j<=n;j++){
                g.drawString(""+j,(1+j)*distance-5,2*distance/5+2);
                g.drawString(""+j,(1+j)*distance-5,11*distance-5);
            } 
            int t=1;
            for(char c='a';c<='j';c++,t++)
                g.drawString(""+c,distance+3,t*distance+distance/5);
         }
         public ChessPiece [] getRedPiece(){
            return redPiece;
         }
         public ChessPiece [] getBlackPiece(){
            return blackPiece;
         }
         public void actionPerformed(ActionEvent e){
             if(step.size()>0)
               handleMouse.cancelAnStep();
             else
              JOptionPane.showMessageDialog(this,"向上已经没有下棋操作,无法再悔棋","提示对话框",
                                            JOptionPane.WARNING_MESSAGE); 
         } 

      

  2.   

    最后是 打开board 对象的函数 public void showBoardManul(){
            stepNumber=1;
            stackStep.clear();
            stackBack.clear(); 
            if(demoOne!=null)
               remove(demoOne);
            try{
                   FileInputStream file_in=new FileInputStream(file);
                   ObjectInputStream object_in=new ObjectInputStream(file_in);
                   demoOne=(ChessBoard)object_in.readObject();
                   file_in.close();
                   object_in.close();
                   ChessPiece [] redPiece=demoOne.getRedPiece();
                   ChessPiece [] blackPiece=demoOne.getBlackPiece();
                   for(int i=0;i<redPiece.length;i++){
                      MouseListener [] listener=redPiece[i].getMouseListeners();
                      for(int k=0;k<listener.length;k++)
                           redPiece[i].removeMouseListener(listener[k]);
                      listener=blackPiece[i].getMouseListeners();
                      for(int k=0;k<listener.length;k++)
                          blackPiece[i].removeMouseListener(listener[k]);
                      MouseMotionListener [] mr=redPiece[i].getMouseMotionListeners();
                      for(int k=0;k<mr.length;k++)
                          redPiece[i].removeMouseMotionListener(mr[k]);
                      mr=blackPiece[i].getMouseMotionListeners();
                      for(int k=0;k<mr.length;k++)
                          blackPiece[i].removeMouseMotionListener(mr[k]);
                   }
                   step=demoOne.getStep();
                   for(int i=step.size()-1;i>=0;i--){
                       stackStep.push(step.get(i)); 
                   }
                   demoOne.remove(demoOne.cancel);
                   restoreChessBoard(step);
                   split.setRightComponent(new JScrollPane(demoOne)); 
            }
            catch(Exception exp){
                add(new JButton("不是棋谱文件"),BorderLayout.CENTER);
            }
        }