问题描述
本人比较菜,按书上的象棋打谱系统的源码进行了一些个性化的修改,但是发现一个非常严重的问题,在ChessBord类里面定义paintcomponent函数的时候如果使用g.drawImage然后保存,整个类里面的部分信息丢失,用g.fillRect却完全不会,我很费解,希望有能力的同学帮我看看现在贴出重点的类和函数ChinaChess类里面主要是点击了saveMenul按钮对board对象进行保存,代码如下
publicclassChinaChessextendsJFrameimplementsActionListener{ChessBoardboard;DemoManulDialogdemoManul;JMenuBarbar;JMenumakeMenu,showMenu,set,music,hf,player;JMenuItemmakeShiZhanManul,makeCanJuManul,openManulAndShow,dkbf;makeShiZhanManul,makeCanJuManul,openManulAndShowJButtonstartMakeManul,saveManul;JTextFieldhintMessage;JRadioButtonMenuItemon,off;JRadioButtonMenuItemn1,n2,n3,n4;staticinta=1;MusicPlayermu;publicChinaChess(){setTitle("中国象棋棋谱制作系统");mu=newMusicPlayer("音乐播放器");mu.setVisible(false);board=newChessBoard();board.setOpen(true);add(board,BorderLayout.CENTER);bar=newJMenuBar();makeMenu=newJMenu("选择制作棋谱的方式");showMenu=newJMenu("棋谱");set=newJMenu("设置");music=newJMenu("音效");dkbf=newJMenuItem("打开播放器");dkbf.addActionListener(this);player=newJMenu("音乐播放器");hf=newJMenu("更换背景");ButtonGroupgroup1=newButtonGroup();ButtonGroupgroup2=newButtonGroup();n1=newJRadioButtonMenuItem("粉红");n2=newJRadioButtonMenuItem("黄");n3=newJRadioButtonMenuItem("蓝");n4=newJRadioButtonMenuItem("绿");on=newJRadioButtonMenuItem("打开声音");off=newJRadioButtonMenuItem("关闭声音");//初始化一个名为;关闭声音的单选项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=newJMenuItem("制作实战棋谱");makeCanJuManul=newJMenuItem("制作残局棋谱");openManulAndShow=newJMenuItem("打开一个棋谱并演示");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=newJButton("开始制作棋谱");startMakeManul.setVisible(false);//设置startMakeManul一开始为不可见startMakeManul.addActionListener(this);saveManul=newJButton("保存棋谱");//初始化saveManul按钮,并且设置文本为"保存棋谱"saveManul.setVisible(false);//设置saveManul一开始为不可见saveManul.addActionListener(this);hintMessage=newJTextField(30);//初始化hintMessage,并且设置大小为30个字符hintMessage.setHorizontalAlignment(JTextField.CENTER);//设置hintMessage为居中hintMessage.setFont(newFont("细黑",Font.PLAIN,15));//设置hintMessage的提示语句的字体为细黑,大小为15hintMessage.setEditable(false);//设置hintMessage为不可编辑hintMessage.setText("请单击菜单,选择制作棋谱的方式或演示已有的棋谱");//设置hintMessage的默认文本为“请单击菜单,选择制作棋谱的方式或演示已有的棋谱”hintMessage.setBackground(Color.green);//设置背景颜色为绿色JPanelnorth=newJPanel();//创建面板对象northnorth.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);}publicvoidactionPerformed(ActionEvente){Stringmessage="单击"开始制作棋谱",然后拖动棋子走棋";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);JFileChooserchooser=newJFileChooser();intstate=chooser.showSaveDialog(null);Filefile=chooser.getSelectedFile();if(file!=null&&state==JFileChooser.APPROVE_OPTION){try{FileOutputStreamout=newFileOutputStream(file);ObjectOutputStreamobjectOut=newObjectOutputStream(out);objectOut.writeObject(board);out.close();objectOut.close();}catch(Exceptionevent){}}}if(e.getSource()==openManulAndShow){JFileChooserchooser=newJFileChooser();intstate=chooser.showOpenDialog(null);Filefile=chooser.getSelectedFile();if(file!=null&&state==JFileChooser.APPROVE_OPTION){demoManul=newDemoManulDialog(file);demoManul.setVisible(true);}}if(e.getSource()==on){board.setOpen(true);}//如果选择了打开音乐选项,把setOpen设为trueif(e.getSource()==off){board.setOpen(false);}//如果选择了关闭音乐选项,把setOpen设置为falseif(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);}}publicstaticvoidmain(Stringargs[]){newChinaChess();}}
解决方案
解决方案二:
第二个为ChessBoard类,主要调用paintComponent函数,类代码如下
publicclassChessBoardextendsJLayeredPaneimplementsActionListener{intm=10,n=9,distance=42;//Toolkittoolkit;//Imageimg;Point[][]playPoint;String[]redName={"帅","士","士","相","相","马","马","车","车","炮","炮","兵","兵","兵","兵","兵"};String[]blackName={"将","仕","仕","象","象","馬","馬","車","車","炮","炮","卒","卒","卒","卒","卒"};ChessPiece[]redPiece;ChessPiece[]blackPiece;ChessBoxredChessBox,blackChessBox;InitPieceLocationinitPieceLocation;InitCanjuinitCanju;HandleMousehandleMouse;ArrayList<Point>step;JButtoncancel;publicChessBoard(){//ChessBoard构造函数setLayout(null);//设置此容器的布局管理器step=newArrayList<Point>();//建立一个ArrayList表记录对弈时棋子所走过棋点initPointAndPiece();//完成棋子和棋点对象的初始化redChessBox=newChessBox(distance,11,7);blackChessBox=newChessBox(distance,11,1);for(inti=0;i<redPiece.length;i++)redChessBox.putPieceToBox(redPiece[i]);for(inti=0;i<blackPiece.length;i++)blackChessBox.putPieceToBox(blackPiece[i]);initPieceLocation=newInitPieceLocation();initPieceLocation.setPoint(playPoint);initPieceLocation.setRedChessPiece(redPiece);initPieceLocation.setBlackChessPiece(blackPiece);initPieceLocation.setRedChessBox(redChessBox);initPieceLocation.setBlackChessBox(blackChessBox);initCanju=newInitCanju();initCanju.setPoint(playPoint);initCanju.setRedChessBox(redChessBox);initCanju.setBlackChessBox(blackChessBox);initCanju.setrule();//调用initCanju中的函数setrule()handleMouse=newHandleMouse();handleMouse.setStep(step);handleMouse.setPoint(playPoint);handleMouse.setRedChessBox(redChessBox);handleMouse.setBlackChessBox(blackChessBox);handleMouse.initStep();//toolkit=getToolkit();//返回此框架的工具包。//img=toolkit.getImage("photo/1.jpg");//获取图片的相对路径cancel=newJButton("悔棋");add(cancel);cancel.setVisible(false);cancel.setSize(60,30);cancel.setLocation(13*distance,(int)(5*distance));cancel.addActionListener(this);}publicvoidstartMakeManul(){cancel.setVisible(true);handleMouse.setRedFirstMove(true);handleMouse.initStep();for(inti=0;i<redPiece.length;i++){MouseListener[]listener=redPiece[i].getMouseListeners();for(intk=0;k<listener.length;k++)redPiece[i].removeMouseListener(listener[k]);listener=blackPiece[i].getMouseListeners();for(intk=0;k<listener.length;k++)blackPiece[i].removeMouseListener(listener[k]);MouseMotionListener[]mr=redPiece[i].getMouseMotionListeners();for(intk=0;k<mr.length;k++)redPiece[i].removeMouseMotionListener(mr[k]);mr=blackPiece[i].getMouseMotionListeners();for(intk=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);}}publicvoidpaintComponent(Graphicsg){//绘制出棋盘上的横线、竖线和其他必要的图形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);}elseif(ChinaChess.a==2){g.setColor(Color.yellow);g.fillRect(0,0,this.getBounds().width,this.getBounds().height);repaint();}elseif(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(inti=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(intj=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(newFont("宋体",Font.BOLD,18));intw=blackPiece[0].getBounds().width;inth=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(intj=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);}intt=1;for(charc='a';c<='j';c++,t++)g.drawString(""+c,distance+3,t*distance+distance/5);}publicChessPiece[]getRedPiece(){returnredPiece;}publicChessPiece[]getBlackPiece(){returnblackPiece;}publicvoidactionPerformed(ActionEvente){if(step.size()>0)handleMouse.cancelAnStep();elseJOptionPane.showMessageDialog(this,"向上已经没有下棋操作,无法再悔棋","提示对话框",JOptionPane.WARNING_MESSAGE);}}
解决方案三:
最后是打开board对象的函数
publicvoidshowBoardManul(){stepNumber=1;stackStep.clear();stackBack.clear();if(demoOne!=null)remove(demoOne);try{FileInputStreamfile_in=newFileInputStream(file);ObjectInputStreamobject_in=newObjectInputStream(file_in);demoOne=(ChessBoard)object_in.readObject();file_in.close();object_in.close();ChessPiece[]redPiece=demoOne.getRedPiece();ChessPiece[]blackPiece=demoOne.getBlackPiece();for(inti=0;i<redPiece.length;i++){MouseListener[]listener=redPiece[i].getMouseListeners();for(intk=0;k<listener.length;k++)redPiece[i].removeMouseListener(listener[k]);listener=blackPiece[i].getMouseListeners();for(intk=0;k<listener.length;k++)blackPiece[i].removeMouseListener(listener[k]);MouseMotionListener[]mr=redPiece[i].getMouseMotionListeners();for(intk=0;k<mr.length;k++)redPiece[i].removeMouseMotionListener(mr[k]);mr=blackPiece[i].getMouseMotionListeners();for(intk=0;k<mr.length;k++)blackPiece[i].removeMouseMotionListener(mr[k]);}step=demoOne.getStep();for(inti=step.size()-1;i>=0;i--){stackStep.push(step.get(i));}demoOne.remove(demoOne.cancel);restoreChessBoard(step);split.setRightComponent(newJScrollPane(demoOne));}catch(Exceptionexp){add(newJButton("不是棋谱文件"),BorderLayout.CENTER);}}