IO流之五子棋进度的保存_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > IO流之五子棋进度的保存

IO流之五子棋进度的保存

 2013/8/7 19:08:22  zhuozhuobeauty  程序员俱乐部  我要评论(0)
  • 摘要:1.java异常机制Java异常(Exception)又称例外,是一种运行时错误。Java异常机制就是对于Java异常的处理方法,使用Java异常机制能提升程序的容错性,从而使程序更加健壮与安全。异常的分类:1.异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception.2.Error和RuntimeException及其子类称为未检查异常(unchecked)
  • 标签:

1.java异常机制

Java异常(Exception)又称例外,是一种运行时错误。Java异常机制就是对于Java异常的处理方法,使用Java异常机制能提升程序的容错性,从而使程序更加健壮与安全。

异常的分类:

1.异常的继承结构:基类为Throwable,Error和Exception继承Throwable,RuntimeException和IOException等继承Exception.

2. Error和RuntimeException及其子类称为未检查异常(unchecked),其它异常称为已检查异常(checked)。

?

Error类描述了Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。

?

RuntimeException包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。

?

JAVA中常见的几种异常:算术异常类(ArithmeticException),空指针异常类(NullPointerException),输入输出异常类(IOException),数组下标越界异常类(ArrayIndexOutOfBoundsException)、类型转换异常类(ClassCastException),数字格式异常(NumberFormatException)等。

?

Java中常有如下三种异常处理方法:

1.使用try-catch-finally语句。try语句块放置可能发生异常的代码,catch语句块捕获这些代码产生的异常,finally语句块无论程序是否有异常发生,都会执行。

2.使用throws关键字抛出异常。若某个方法可能发生异常,但不想在当前方法中处理这个异常,那就可以利用throws关键字在该方法抛出异常,然后在调用该方法的代码中捕获该异常进行处理。

3.自定义异常类与throw关键字

关于自定义异常类的使用,分为如下几个步骤:

1)创建自定义异常类,利用继承思想

2)在方法中通过throw关键字抛出异常对象

3)若在当前抛出异常的方法中处理,使用第一种方法,否则使用第二种方法。

**throw和throws的区别

区别一:
???????????? throw 是语句抛出一个异常;throws 是方法抛出一个异常;?
????????????? throw语法:throw <异常对象>?
????????????? 在方法声明中,添加throws子句表示该方法将抛出异常。?
???????????? throws语法:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]?
???????????? 其中:异常类可以声明多个,用逗号分割。?
区别二:
????????? throws可以单独使用,但throw不能;?
区别三:
??????????? throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获。??
throws E1,E2,E3 只是告诉程序这个方法可能会抛出这些个异常,方法的调用者可能要处理这些异常。而这些异常E1,E2,E3可能是该函数体产生的。 而throw是明确之处这个地方要抛出这个异常。 void doA() throws Exception1, Exception3 {?? try {???? ……
? } catch(Exception1 e) {???? throw e;
? } catch(Exception2 e) {
??? System.out.println("出错了");?? }
? if (a != b)
??? throw new Exception3("自定义异常"); }

2.实现五子棋进度的保存

感谢队友王小二的大力支持~~

保存进度,其实就是把我们所画的图形存到文件中。因此,我们需要一个文件打开和一个文件写入的方法,当然要实现保存,必须将保存与一个按钮,及其监听器相互绑定起来。

下面又是代码时间~~这次让我们先从主函数开始

class="java">import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Chesstry extends JPanel {
	String fileName = "F:/五子棋.txt";
	Test test = new Test();
	private int Longer;
	List<Chess> list = new ArrayList();
	Graphics g;
	ChessListener cl;

	public static void main(String[] args) {
		// 实例化一个面板对象
		Chesstry cb = new Chesstry();
		cb.Beautiful();
	}

	// 写一个设置棋盘的方法
	public void Beautiful() {
		JFrame jf = new JFrame();
		jf.setSize(600, 620);
		jf.setTitle("五子棋");
		jf.setLocationRelativeTo(null);
		JPanel eastJpanel = new JPanel();
		// 设置东边的布局的颜色
		eastJpanel.setBackground(new Color(227, 160, 200));
		// 设置东边的大小
		eastJpanel.setPreferredSize(new Dimension(100, 0));
		jf.add(eastJpanel, BorderLayout.EAST);
		// 在东边添加两个按钮
		JButton jb1 = new JButton("开始");
		JButton jb2 = new JButton("退出");
		JButton jb3 = new JButton("黑子先手");
		JButton jb4 = new JButton("白子先手");
		JButton jb5 = new JButton("保存");
		JButton jb6 = new JButton("打开");
		// 将按钮加到面板上
		eastJpanel.add(jb1);
		eastJpanel.add(jb2);
		eastJpanel.add(jb3);
		eastJpanel.add(jb4);
		eastJpanel.add(jb5);
		eastJpanel.add(jb6);
		// 给按钮添加监听器
		//匿名内部类
		jb1.addActionListener(new ActionListener() {
        
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("开始")) {
					test.setB1("1");
					System.out.println("          " + test.getB1());
				}
			}
		});
		
		jb2.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("退出")) {
					
					int i = JOptionPane.showConfirmDialog(null, "请点击关闭按钮退出程序");
					if (i == 0) {
						System.exit(0);
					}
				}
			}
		});
		
		jb3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("黑子先手")) {
					test.setB3("1");
				}

			}
		});
		
		jb4.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("白子先手")) {
					test.setB3("-1");
				}

			}
		});
		
		jb5.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("保存"))
					;
				try {
					// 调用写入方法
					write(fileName);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
		
		jb6.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (e.getActionCommand().equals("打开")) {
					try {
						// 调用读取文件的方法
						open(fileName);
					} catch (IOException e1) {
						e1.printStackTrace();
					} catch (ClassNotFoundException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
		// 设置棋盘的颜色
		this.setBackground(Color.PINK);
		jf.add(this, BorderLayout.CENTER);
		jf.setVisible(true);
		g = jf.getGraphics();
		// 获取绘画的图形
		Graphics g = this.getGraphics();
		// 实例化一个ChessLIstener类的监听对象
		// ChessListener cl = new ChessListener(g,b1, b2,b3,b4);
		ButtonListener c2 = new ButtonListener(jb3, jb4);
		// 给事件源棋盘面板添加鼠标监听器方法,绑定事件处理类的对象
		cl = new ChessListener(g, test, list);
		this.addMouseListener(cl);
		// 绘制棋盘
		jf.setDefaultCloseOperation(3);
	}

	// 重绘操作,重写重绘方法
	public void paint(Graphics g) {
		super.paint(g);
		drawChessTable(g);
	}

	// 绘制棋盘
	private void drawChessTable(Graphics g) {
		for (int i = 0; i < Config.ROW; i++) {
			g.drawLine(i * Config.SIZE + Config.X, Config.Y, i * Config.SIZE
					+ Config.X, Config.Y + (Config.COLUMN - 1) * Config.SIZE);
		}
		for (int i = 0; i < Config.COLUMN; i++) {
			g.drawLine(Config.X, i * Config.SIZE + Config.Y, Config.X
					+ (Config.ROW - 1) * Config.SIZE, i * Config.SIZE
					+ Config.Y);
		}
	}
     //写一个写入方法,将数据保存到文件里面
	public boolean write(String fileName) throws IOException {
		this.list = cl.list;
	     //写入对象
		FileOutputStream fos = new FileOutputStream(fileName);
		ObjectOutputStream out = new ObjectOutputStream(fos);
		// 写入队列的长度
		DataOutputStream dos = new DataOutputStream(fos);
		//writeInt方法,将棋子个数写入文件中
		dos.writeInt(list.size());
		for (int i = 0; i < list.size(); i++) {
			Chess chess = list.get(i);
			out.writeObject(chess);
//			System.out.println("aaaaaaaaaaa");
			out.flush();
		}
		//写完文件后关闭文件
		dos.close();
		out.close();
		return true;
	}
        //定义一个打开文件的方法
	public boolean open(String fileName) throws IOException,ClassNotFoundException {
		// for (int i = 0; i < list.size(); i++) {
		FileInputStream fis = new FileInputStream(fileName);
		ObjectInputStream input = new ObjectInputStream(fis);
		//首先读取原来队列的长度,即对象的个数
		DataInputStream  dis = new DataInputStream(fis);
		int listSize = dis.readInt();
		for (int i = 0; i <listSize; i++) {
			//强制转型,读出对象
			Chess chess = (Chess) input.readObject();
			//判断并设置画布的颜色
			if(chess.getColor()==1){
				g.setColor(Color.black);
			}else{
				g.setColor(Color.WHITE);
			}
			System.out.println(chess.getI()+"ppppppppppppppp"+ chess.getJ());
			g.fillOval(chess.getI()+Config.CHESS_SIZE /4, chess.getJ()+Config.CHESS_SIZE ,
					Config.SIZE, Config.SIZE);
			// chess = (Chess) input.readObject();
		}
		//数据读取完毕,关闭文件
		dis.close();
		input.close();
		return true;
	}
}

?


?接下来是棋子监听器

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JOptionPane;

public class ChessListener extends MouseAdapter {
	private Graphics g;
	private int b3=0;// 判断黑白棋的依据
	private Win win = new Win();
	List<Chess> list;
	int longer = 0;
	int count = 0;// 保证黑白子交替出现
	int flag = 0;

	Test test;

	public ChessListener(Graphics g, Test test, List<Chess> list) {
		// TODO Auto-generated constructor stub
		this.g = g;
		this.test = test;
		this.list = list;
		
		System.out.println(test.getB1() + "b2::::::::" + test.getB2());
	}

	public void mouseReleased(MouseEvent e) {
		// System.out.println("222222222222 here b1 is: "+test.getB1());
		if (test.getB1().equals("1")) {
			int x1 = e.getX();// 得到坐标
			int y1 = e.getY();
//			System.out.println(x1+"           "+y1);
			for (int i = 0; i < Config.ROW; i++) {
				for (int j = 0; j < Config.COLUMN; j++) {
					// 判断此点是否已经被落子
					if (Config.array[i][j] == 0) {
						// 得到当前的坐标
						int x = Config.X + Config.CHESS_SIZE * i
								- Config.CHESS_SIZE / 2;
						int y = Config.Y + Config.CHESS_SIZE * j
								- Config.CHESS_SIZE / 2;
						if (x1 > (Config.X + Config.CHESS_SIZE * i - Config.CHESS_SIZE / 3)
								// 如果在三分之一范围内就落子
								&& x1 < (Config.X + Config.CHESS_SIZE * i + Config.CHESS_SIZE / 3)
								&& y1 > (Config.Y + Config.CHESS_SIZE * j - Config.CHESS_SIZE / 3)
								&& y1 < (Config.Y + Config.CHESS_SIZE * j + Config.CHESS_SIZE / 3)) {
							// 下黑子
							if (count == 0) {
								g.setColor(Color.black);
								count++;
								b3 = 1;
							} else {
								// 下白子
								g.setColor(Color.WHITE);
								count--;
								b3 = -1;
							}				
							g.fillOval(x, y, Config.CHESS_SIZE,
									Config.CHESS_SIZE);
							Chess chess = new Chess(x, y, b3);// 实例化一个棋子对象,存储当前的坐标及颜色
							System.out.println(x+"oooooo"+y);
							// 将该棋子对象存到队列里面去
							list.add(chess);
							Config.array[i][j] = b3;
							if (win.validater(i, j)) {
								if (b3 == 1) {
									JOptionPane.showMessageDialog(null,
											"恭喜,黑棋胜利!");
									test.setB1("0");
									for (int i1 = 0; i1 < Config.ROW; i1++) {
										for (int j1 = 0; j1 < Config.COLUMN; j1++) {
											Config.array[i1][j1] = 0;
										}
									}
								} else {
									JOptionPane.showMessageDialog(null,
											"恭喜,白棋胜利!");
									test.setB1("0");
									for (int i1 = 0; i1 < Config.ROW; i1++) {
										for (int j1 = 0; j1 < Config.COLUMN; j1++) {
											// Config.array[i][j]=0;
											Config.array[i1][j1] = 0;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}

?

按钮监听器

import java.awt.Component;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JButton;

public class ButtonListener extends MouseAdapter{
	private JButton jb3,jb4;
	private Component a;
	public ButtonListener(JButton jb3,JButton jb4){
	
		this.jb3 = jb3;
		this.jb4 = jb4;
	}
	


	}

?

/**
 * 五子棋配置信息的接口
 *
 */
public interface Config {

	int X = 20;
	
	int Y = 20;
	
	int ROW = 16;
	
	int COLUMN = 16;
	
	int SIZE = 30;
	
	int CHESS_SIZE = 30;
	
	int  array[][] = new int[ROW][COLUMN];

	
	
}

?

序列化棋子

//实例化一个棋子类可以用来反序列化棋子
import java.io.Serializable;

public class Chess implements Serializable {
private int i;
private int j;
private int Color;
public Chess(int i ,int j,int Color){
	this.i=i;
	this.j=j;
	this.Color=Color;
}
public int getI() {
	return i;
}
public void setI(int i) {
	this.i = i;
}
public int getJ() {
	return j;
}
public void setJ(int j) {
	this.j = j;
}
public int getColor() {
	return Color;
}
public void setColor(int color) {
	Color = color;
}
}

?

测试类

//用于测试按钮监听器是否奏效的测试类
public class Test {
	String b1="0", b2="0",b3="0",b4="0";

	public String getB1() {
		return b1;
	}

	public String getB2() {
		return b2;
	}

	public String getB3() {
		return b3;
	}
	public void setB1(String b1) {
		this.b1 = b1;
	}

	public void setB2(String b2) {
		this.b2 = b2;
	}

	public void setB3(String b3) {
		this.b3 = b3;
	}
}

?

备注:关于文件写入与输出的类

第一,ObjectOutputStream 和 ObjectInputStream 分别与 FileOutputStream 和 FileInputStream 一起使用时,可以为应用程序提供对对象图形的持久存储。
第二,类 DataOutputStream
数据输出流允许应用程序以适当方式将基本 Java 数据类型写入输出流中。然后,应用程序可以使用数据输入流将数据读入。


看一下效果图



?

  • 大小: 21.5 KB
  • 查看图片附件
  • 相关文章
发表评论
用户名: 匿名