本人比较菜,按书上的象棋打谱系统的源码进行了一些个性化的修改,但是发现一个非常严重的问题,在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();
}
}
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();
}
}
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);
}
}
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);
}
}