install4j将java程序生成为exe教程

1,General setting

首先设置你要打包的工程名字,如版本号,全称,简称等。如果有中文,会以方框表示的。不过,打包后会显示回中文的。再按右上角的右箭头,跳入下一个窗口。输入最小的jer版本号及最大的,最大的可以为空。再按右箭头,选择安装界面的语言。第一个为中文。再跳入下一个窗口,这里选择你生成exe文件后所在的路径及你生成的EXE文件名称,一路按next到下一个选项。

2,File

点击Add Files按钮选择你要打包的jar文件及相关文件所在的路径。(如果你用的是netbeans的话,在生成后会有一个disc的文件夹,建议先在这个文件夹里测试,将所有的要使用到的文件全部放在这个文件夹里)。选定了要安装的文件的文件夹后。按NEXT,在这个窗口里,是选择那些文件不打包的。打上勾的为不打包。一路NEXT到下一个窗口。

3,Launchers

双击new launchers图标,在新弹出的窗口里在Executable name里输入你要生成的exe文件名,(例如,如果输入的是install,则生成的install.exe),下面的directory里输入. 即可,选中前两个复选框。点击下一步,在下一个窗口里要你输入两个小图标,分别是16*16,32*32的。最好是png的格式。再点击一步,先在class path里添加上你的jar文件,即生成出来的jar文件。然后在main class选择你的程序入口。一路next到OK。

4,Install

点击右上角的右箭头,跳到Actions标签窗口。选中Create program group,后,在右边window->program group name里输入你的生成在程序组里的名称,即点击开始->程序后,所看到的名称,如果输入的是中文会以方格形式显示。再点击右箭头,直接将disc文件添加进来,即将该目录下的所有文件也打包。一路按右箭头,跳到media。

5,Media

双击new media file图标,在新的窗口里选择生成文件的操作平台,选上window,再按next,在第一个文本框里输入${compiler:sys.fullName},意思是该文件的全称。在下面的文本框里输入你要安装该软件的路径,(如,要将到D盘,将输入D:\),一路next到第6步(bundlen JRE),你要生成一个自带JRE的EXE程序,将要下载JRE的。再按next到第7步,在第7步里,点击exclude file,在窗口中你可以筛选一下那些文件不要生成,选中为不生成。一路next到ok.

6,Bulid

有Test Bulid和start Bulid,可以先test下,如果没有错就可以生成EXE文件了。

参考文章http://hi.baidu.com/zhangqichun/blog/item/c5036711b071080a203f2ee4.html

java获取当前文件路径的简单方法

1、利用System.getProperty()函数获取当前路径:
System.out.println(System.getProperty(“user.dir”));//user.dir指定了当前的路径

2、使用File提供的函数获取当前路径:
File directory = new File(“”);//设定为当前文件夹
try{
System.out.println(directory.getCanonicalPath());//获取标准的路径
System.out.println(directory.getAbsolutePath());//获取绝对路径
}catch(Exceptin e){}

File.getCanonicalPath()和File.getAbsolutePath()大约只是对于new File(“.”)和new File(“..”)两种路径有所区别。

# 对于getCanonicalPath()函数,“.”就表示当前的文件夹,而”..“则表示当前文件夹的上一级文件夹
# 对于getAbsolutePath()函数,则不管”.”、“..”,返回当前的路径加上你在new File()时设定的路径
# 至于getPath()函数,得到的只是你在new File()时设定的路径

比如当前的路径为 C:\test :
File directory = new File(“abc”);
directory.getCanonicalPath(); //得到的是C:\test\abc
directory.getAbsolutePath(); //得到的是C:\test\abc
direcotry.getPath(); //得到的是abc

File directory = new File(“.”);
directory.getCanonicalPath(); //得到的是C:\test
directory.getAbsolutePath(); //得到的是C:\test\.
direcotry.getPath(); //得到的是.

File directory = new File(“..”);
directory.getCanonicalPath(); //得到的是C:\
directory.getAbsolutePath(); //得到的是C:\test\..
direcotry.getPath(); //得到的是..

另外:System.getProperty()中的字符串参数如下:

System.getProperty()参数大全
# java.version Java Runtime Environment version
# java.vendor Java Runtime Environment vendor
# java.vendor.url Java vendor URL
# java.home Java installation directory
# java.vm.specification.version Java Virtual Machine specification version
# java.vm.specification.vendor Java Virtual Machine specification vendor
# java.vm.specification.name Java Virtual Machine specification name
# java.vm.version Java Virtual Machine implementation version
# java.vm.vendor Java Virtual Machine implementation vendor
# java.vm.name Java Virtual Machine implementation name
# java.specification.version Java Runtime Environment specification version
# java.specification.vendor Java Runtime Environment specification vendor
# java.specification.name Java Runtime Environment specification name
# java.class.version Java class format version number
# java.class.path Java class path
# java.library.path List of paths to search when loading libraries
# java.io.tmpdir Default temp file path
# java.compiler Name of JIT compiler to use
# java.ext.dirs Path of extension directory or directories
# os.name Operating system name
# os.arch Operating system architecture
# os.version Operating system version
# file.separator File separator (“/” on UNIX)
# path.separator Path separator (“:” on UNIX)
# line.separator Line separator (“\n” on UNIX)
# user.name User’s account name
# user.home User’s home directory
# user.dir User’s current working directory

参考地址:http://www.cnblogs.com/ymind/archive/2012/04/22/2465629.html

双卡双待的android手机联想A750到底怎么样

我承认我一直都比较喜欢双卡双待的手机,当然很多朋友会说“市面上双卡双待的手机还少啊”。的确,目前我国很多山寨手机都具备双卡双待功能,并且是超大的喇叭和电池容量,我上班以来一直用的是移动的号,但是移动的3G真的不给力,居然不跟国际接轨,不是WCDMA,搞个TD-SCDMA,而目前的主流android手机都是GSM,WCDMA制式。如果我想用移动的3G的话,我必须得换手机了,得换成目前市面上的GSM,TD-SCDMA制式的手机,这种类型的手机不是主流哦,选择的余地不是很大,很不爽,为了享受3G,我一直想要一个联通的号,以后移动的号只用来接电话,联通的手机号什么都干,打电话便宜,上网还给力。我同时还喜欢android智能手机,目前双卡双待的android手机就不是很多了,我印象中联想有,酷派有,htc好像有,别的我就不知道了。东瞅西瞅,我看中了联想的A750。说实话,我不喜欢这个手机的外型,感觉不酷,很山寨。同事我也不喜欢它的显示效果,虽然它的分辨率据说是480*800,不算太低,但是看上去并不咋滴,依然感觉很山寨。
但是我还是买了联想A750,现在我只想搞个价钱不贵,配置还凑合的双卡双待android手机,这一点联想A750比较符合吧。4G的ROM(实际我的机器只有2G,也算够用),512的RAM,联通充话费送手机,1599元,淘宝上买这个手机是1000元左右。反正我也想办个联通3G卡,就充话费送也行,我选择的是96元B套餐,一个月返53元,自己还得充43元话费,目前里面有324元可用余额。套餐里面是450分钟国内电话,80M国内流量。超出套餐是每分钟1.5毛,1M流量3毛。送话费两年,先就这样用着吧

java常用数据类型的转换

自己经常容易忘记java一些类型间的转换
特在网上搜索了一下,进行备忘

数据类型的互相转换

数据类型 位长 取值范围
byte 8 -128—127
short 16 -32768—32767
int 32 -2147483648—2147483647
long 64 -9223372036854775808—9223372036854775807
float 32 -1.4E—45~~-3.4E+38—1.4E—45~~3.4E+38
double 64 – 4.9E—324~~-1.7E+308—4.9E—324~~1.7E+308
char    
boolean   true 、false
String    

 

 

数字类型 转换为 字符串类型

转换类型

方法

例子

字节型整数类(byte) Byte.toString(byte) String str= Byte.toString(byte)
短整型整数类(short) Short.toString(short) String str= Short.toString(short)
整数类(int) Integer.toString(int) String str= Integer.toString(int)
长整形整数类(long) Long.toString(long) String str= Long.toString(long)
单精度浮点数类(float) Float.toString(float) String str= Float.toString(float)
双精度浮点数类(double) Double.toString(double) String str= Double.toString(double)
     

 

字符串类型 转换为 数字类型

转换类型

方法

例子

字节型整数类(byte) Byte.parseByte(String) byte toByte= Byte.parseByte(String)
短整型整数类(short) Short.parseShort(String) short toShort= Short.parseShort(String)
整数类(int) Integer.parseInteger(String) int toInt= Integer.parseInteger(String)
长整形整数类(long) Long.parseLong(String) long toLong= Long.parseLong(String)
单精度浮点数类(float) Float.parsevFloat (String) float toFloat= Float.parsevFloat (String)
双精度浮点数类(double) Double.parseDouble(String) double toDouble= Double.parseDouble(String)
     

 

数字类型 ß 日期类型 à 字符串类型

转换类型

方法
数字类型à日期类型 1.        Calendar.set(int year,int month,int date)

2.   Calendar.set(int year,int month,int date, int hour,int minute,int second)

日期类型à数字类型 Calendar.get(int field)

计算机考研必备的计算机视频

一、数据结构
《数据结构教程 清华严蔚敏主讲》MP4播放版
并非如题全为mp4版,从37讲开始改为mkv容器盛放

《石油大学-数据结构30讲 适合在MP4上看 》RMVB格式
具体不详,snail有推荐,遂列出

《IT播吧 - 思成老师出品的数据结构的系列视频教程》[压缩包]
评论者语:大学里的老师都是照本宣科,理论知识一套一套的,却不见如何用计算机语言实现数据结构,还美其名曰:只讲数据结构,不讲如何编程,看到这个播吧将理论与实践相结合,真是太感谢了!
二、计算机组成原理

《计算机组成原理42讲 电子科技大学》[压缩包]
同为电子科技大学的罗克露教授,与snail推荐源主要异同由大家品鉴

《吉林大学-计算机组成原理48+2辅导》全部更新完成
包括白中英的题库及解答
评论总说没有源,有的人就说有源,鬼才知道有没有源,下不下载自己决定

《自考视频 计算机组成原理(专)2套(发布完毕)》适合自学考试
包括上面的电子科技大学视频,另外有石油大学的38讲
三、计算机操作系统

《西北工业大学网络教育学院课件》更新课件:操作系统
其中包括汇编程序设计和操作系统,大家可以只选操作系统下载

《计算机操作系统》(Computer Operating System)视频教程
是清华大学出版社出版,张尧学,史美林编著第2版的视频教程,在兴趣的同学可以看看
四、计算机网络

《计算机网络教程1-11+全部》更新重发 [48课时+3课时辅导]
这个就是snail推荐的吉林大学远程教育的完整源版

《北大严伟教授的计算机网络系列讲座》
发布者语:本人看过很多视频教程,觉得这个教程完全可以算得上是最上品,内容上提炼的很好,看了这个再去看书的话,保你可以完全理解,而且课上的十分生动,带有不少的动画,很难找得出能够比配的教程·希望对大家有帮助!

《计算机网络基础陆魁军》
浙江大学远程教育,谢希仁版教材

下面有几个文本类

《2009年全国硕士研究生入学统一考试: 计算机学科联考全程辅导》[PDF]
多的不用说,自己看下就知道了

《计算机组成原理考研指导》1.0[压缩包]
发布者语:考研经典讲解,考计算机的必看

《经典操作系统课件-适合初学者》1.0[光盘镜像]
发布者语:我上操作系统时,导师给的课件,很适合初学者,新手可以看一看

《数据结构习题集-1800道》[光盘镜像] 注:无源
大家都说没有源,楼主说晚上才会做,可以请楼主发到你的邮箱里,如果他愿意的话
另外貌似复试的话也许会考到离散数学的部分内容,不知道会不会。。。

《上海交大离散数学更新完毕》[RMVB]

 

原文来源http://www.cskaoyan.com/thread-42606-1-1.html

android读取、写入文件

这是一个简单的将文本框里的内容写入指定文件的程序,同时还能读去指定文件名里面的内容
FileService.java实现了读取和写入方法
程序界面截图如下
android读取写入文件
里面的源码是:

package com.daozhao.android;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.FileInputStream;

import android.content.Context;

public class FileService {
	private Context context;
	
	public FileService(Context context) {
		this.context = context;
	}
	
	/**
	 * 一私有文件保存内容
	 * @param filename 文件名称
	 * @param content 文件内容
	 * @throws Exception
	 */
	public void save(String filename, String content) throws Exception {
		FileOutputStream fos = context.openFileOutput(filename, Context.MODE_PRIVATE);
		fos.write(content.getBytes());
		fos.close();
	}
	
	/**
	 * 一读取文件内容
	 * @param filename 文件名称
	 * @param content 文件内容
	 * @throws Exception
	 */
	public String readFile(String filename) throws Exception {
		FileInputStream fis = context.openFileInput(filename);
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		while((len = fis.read(buffer)) != -1) {
			baos.write(buffer, 0, len);
		}
		byte[] data = baos.toByteArray(); //得到文件的二进制数据
		baos.close();
		fis.close();
		return new String(data);
	}
}

MainActivity.java是主Activity
源代码如下:

package com.daozhao.android;

import android.app.Activity;
import android.os.Bundle;
import android.widget.*;
import android.util.Log;
import android.view.*;

public class MainActivity extends Activity {
	private static final String TAG = "MainActivity";
    private FileService fs;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        fs = new FileService(this);
        
        Button button = (Button) this.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				EditText fileName = (EditText) findViewById(R.id.filename);
				EditText fileContent = (EditText) findViewById(R.id.filecontent);
				String filename = fileName.getText().toString();
				String filecontent = fileContent.getText().toString();
				try {
					fs.save(filename,filecontent);
					//输出操作成功的信息
					Toast.makeText(MainActivity.this, R.string.success, 1).show();
				} catch(Exception e) {
					Log.e(TAG, e.toString());
					Toast.makeText(MainActivity.this, R.string.error, 1).show();
				}
			}
        	
        });
        
        
        Button read = (Button) this.findViewById(R.id.read);
        read.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				EditText fileName = (EditText) findViewById(R.id.filename);
				EditText fileContent = (EditText) findViewById(R.id.filecontent);
				String filename = fileName.getText().toString();
				String str = null;
				String filecontent = fileContent.getText().toString();
				try {
					str = fs.readFile(filename);
					fileContent.setText(str);
				} catch(Exception e) {
					Log.e(TAG, e.toString());
					fileContent.setText("");
					Toast.makeText(MainActivity.this, R.string.error, 1).show();
				}
			}
        	
        });
    }
}

android常用的junit

在做android应用时经常要用测试,功能经测试实现了后才最后面的收尾工作,所以在eclipse里面,我们经常会做这样一个操作“run as Android Junit Test”
但是我们不要忘了在项目的配置文件AndroidMainfest.xml里面进行适当的配置
Android Junti Test

图中加/////的两行就是必须要添加的哦。同时大家要注意包的一致性。

不要用蛋疼的lomboz eclipse了

之前我看马士兵老师的视频,里面推荐用lomboz eclipse,因为它对连接数据库和做jsp server很方便,所以我就也跟着下载了,发现lomboz eclipse的主页的url也不一样了(跟02年的视频里面相比)。因为lomboz eclipse不支持win64 最后我被迫换成win32,换成win32还是有不少问题,show view里面的东西也没有视频里面的那个连接了,最终我放弃了lomboz eclipse。
现在我用sqlexplorer 效果是一样的,觉得当时死扣lomboz eclipse真是没必要,还把我的系统给换了,郁闷。大家放弃lomboz eclipse吧,我感觉现在用lomboz eclipse的人不多,看来我不是一般的out。
想知道怎么安装sqlexplorer可以看

java双缓冲技术

最近想弄一个小小的程序练习和巩固自己的java基础,既然学习了awt,所以现在编的程序自然是有简单的界面的,不能老是停留在原始的黑乎乎的dos窗口了。最近的做的东西我一般都会用到drawString(String,int,int)方法,主要是我想将自己程序里面设置的某些变量的值写在窗体中,那样我自己也好看一下自己的这些变量是不是在看自己的意愿在执行,其实它就等同于某些同志喜欢将部分变量的值用system.out.println(“”);输出是一样的,只是对我来说有时不方便看console而已。

经常我们会看到drawString方法输出的值虽然在改变,但是我们真的看不太清它变成多少了。
我先截个图给大家看看
drawstring

这只是一个简单的例子程序,都容易出现这种状况的话,复杂的多变的图形界面程序怎么办,这是我们一般会用一个线程对该窗体来调用repaint(); 但是这同时也带来一个问题,那就是人的肉眼明显感觉到画面在闪烁,那这又该怎么办呢?现在我们今天说的主角就上场了,没错,我们得利用java的双缓冲技术了。
我把测试程序的源代码公布一下,欢迎大家探讨;
MyTestDoubleBuffering.java的源代码如下

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class MyTestDoubleBuffering {
	public static void main(String[] args) {
		new TestFrame("测试双缓冲");
	}
}

class TestFrame extends Frame {
	Random r = null;
	Image offScreenImage =null;
	TestFrame(String name) {
		super(name);
		setSize(400,300);
		setLocation(300,200);
		setLayout(new BorderLayout());
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				setVisible(false);
				System.exit(0);
			}
			
		});
		Button c = new Button("Click");
		c.setSize(19, 19);
		c.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent arg0) {
				test(getGraphics());
			}	
		});
		add(c,BorderLayout.SOUTH);
		setVisible(true);
		
		new Thread(new PaintThread()).start();
		
	}
	
	public void test(Graphics g) {
		r = new Random();
		g.drawString(r + "",100,200);
	}
	
	public void update(Graphics g) {
		if(offScreenImage == null){
			offScreenImage = this.createImage(400,300);
		}
		Graphics gOffScreen = offScreenImage.getGraphics();
		Color c = gOffScreen.getColor();
		gOffScreen.setColor(Color.white);
		gOffScreen.fillRect(0, 0, 400, 300);
		gOffScreen.setColor(c);
		paint(gOffScreen);
		g.drawImage(offScreenImage, 0, 0, null);
	}
	
	class PaintThread implements Runnable {
		public void run() {
			while (true) {
				repaint();
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

分享一个java做的五子棋

有截图,个人认为这个五子棋做还可以,能人机对弈和人人对战,设置棋盘的大小
Java五子棋
GoBang.java的源代码如下:

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import javax.swing.*;
import java.io.PrintStream;
import javax.swing.JComponent;
import javax.swing.JPanel;

/*
 *main方法创建了ChessFrame类的一个实例对象(cf),
 *并启动屏幕显示显示该实例对象。
 **/
public class GoBang {
	public static void main(String args[]){
		ChessFrame cf = new ChessFrame();
		cf.show();
	}
}

/*
 *类ChessFrame主要功能是创建五子棋游戏主窗体和菜单
 **/
class ChessFrame extends JFrame implements ActionListener {
	private String[] strsize={"20x15","30x20","40x30"};
	private String[] strmode={"人机对弈","人人对弈"};
	public static boolean iscomputer=true,checkcomputer=true;
	private int width,height;
	private ChessModel cm;
	private MainPanel mp;
	
	//构造五子棋游戏的主窗体
	public ChessFrame() {
		this.setTitle("五子棋游戏");
		cm=new ChessModel(1);
		mp=new MainPanel(cm);
		Container con=this.getContentPane();
		con.add(mp,"Center");
		this.setResizable(false);
		this.addWindowListener(new ChessWindowEvent());
		MapSize(20,15);
		JMenuBar mbar = new JMenuBar();
		this.setJMenuBar(mbar);
		JMenu gameMenu = new JMenu("游戏");
		mbar.add(makeMenu(gameMenu, new Object[] {
			"开局", "棋盘","模式", null, "退出"
			}, this));
		JMenu lookMenu =new JMenu("视图");
		mbar.add(makeMenu(lookMenu,new Object[] {
			"Metal","Motif","Windows"
			},this));
		JMenu helpMenu = new JMenu("帮助");
		mbar.add(makeMenu(helpMenu, new Object[] {
			"关于"
		}, this));
	}

	//构造五子棋游戏的主菜单
	public  JMenu makeMenu(Object parent, Object items[], Object target){
		JMenu m = null;
		if(parent instanceof JMenu)
			m = (JMenu)parent;
		else if(parent instanceof String)
			m = new JMenu((String)parent);
		else
			return null;
		for(int i = 0; i < items.length; i++)
			if(items[i] == null)
				m.addSeparator();
			else if(items[i] == "棋盘"){
				JMenu jm = new JMenu("棋盘");
				ButtonGroup group=new ButtonGroup();
				JRadioButtonMenuItem rmenu;
				for (int j=0;j<strsize.length;j++){
					rmenu=makeRadioButtonMenuItem(strsize[j],target);
					if (j==0)
						rmenu.setSelected(true);
					jm.add(rmenu);
					group.add(rmenu);
				}
				m.add(jm);
			}else if(items[i] == "模式"){
				JMenu jm = new JMenu("模式");
				ButtonGroup group=new ButtonGroup();
				JRadioButtonMenuItem rmenu;
				for (int h=0;h<strmode.length;h++){
					rmenu=makeRadioButtonMenuItem(strmode[h],target);
					if(h==0)
						rmenu.setSelected(true);
					jm.add(rmenu);
					group.add(rmenu);
				}
				m.add(jm);
			}else
				m.add(makeMenuItem(items[i], target));
		return m;
	}
	
	//构造五子棋游戏的菜单项
	public  JMenuItem makeMenuItem(Object item, Object target){
		JMenuItem r = null;
		if(item instanceof String)
			r = new JMenuItem((String)item);
		else if(item instanceof JMenuItem)
			r = (JMenuItem)item;
		else
			return null;
		if(target instanceof ActionListener)
			r.addActionListener((ActionListener)target);
		return r;
	}
	
	//构造五子棋游戏的单选按钮式菜单项
	public  JRadioButtonMenuItem makeRadioButtonMenuItem(
    	Object item, Object target){
    	JRadioButtonMenuItem r = null;
    	if(item instanceof String)
    		r = new JRadioButtonMenuItem((String)item);
    	else if(item instanceof JRadioButtonMenuItem)
    		r = (JRadioButtonMenuItem)item;
    	else
    		return null;
    	if(target instanceof ActionListener)
    		r.addActionListener((ActionListener)target);
    	return r;
    }
    
    public void MapSize(int w,int h){
    	setSize(w * 20+50 , h * 20+100 );
    	if(this.checkcomputer)
    		this.iscomputer=true;
    	else
    		this.iscomputer=false;
    	mp.setModel(cm);
    	mp.repaint();
    }
    
    public boolean getiscomputer(){
    	return this.iscomputer;
    }
    
    public void restart(){
    	int modeChess = cm.getModeChess();
    	if(modeChess <= 3 && modeChess >= 1){
    		cm = new ChessModel(modeChess);
    		MapSize(cm.getWidth(),cm.getHeight());
    	}else{
    		System.out.println("\u81EA\u5B9A\u4E49");
    	}
    }
    
    public void actionPerformed(ActionEvent e){
    	String arg=e.getActionCommand();
    	try{
    		if (arg.equals("Windows"))
    			UIManager.setLookAndFeel(
    				"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    		else if(arg.equals("Motif"))
				UIManager.setLookAndFeel(
					"com.sun.java.swing.plaf.motif.MotifLookAndFeel");
			else
				UIManager.setLookAndFeel(
					"javax.swing.plaf.metal.MetalLookAndFeel" );
			SwingUtilities.updateComponentTreeUI(this);
		}catch(Exception ee){}
		if(arg.equals("20x15")){
			this.width=20;
			this.height=15;
			cm=new ChessModel(1);
			MapSize(this.width,this.height);
			SwingUtilities.updateComponentTreeUI(this);
		}
		if(arg.equals("30x20")){
			this.width=30;
			this.height=20;
			cm=new ChessModel(2);
			MapSize(this.width,this.height);
			SwingUtilities.updateComponentTreeUI(this);
		}
		if(arg.equals("40x30")){
			this.width=40;
			this.height=30;
			cm=new ChessModel(3);
			MapSize(this.width,this.height);
			SwingUtilities.updateComponentTreeUI(this);
		}
		if(arg.equals("人机对弈")){
			this.checkcomputer=true;
			this.iscomputer=true;
			cm=new ChessModel(cm.getModeChess());
			MapSize(cm.getWidth(),cm.getHeight());
			SwingUtilities.updateComponentTreeUI(this);
		}
		if(arg.equals("人人对弈")){
			this.checkcomputer=false;
			this.iscomputer=false;
			cm=new ChessModel(cm.getModeChess());
			MapSize(cm.getWidth(),cm.getHeight());
			SwingUtilities.updateComponentTreeUI(this);
		}
		if(arg.equals("开局")){
			restart();
		}
		if(arg.equals("关于"))
			JOptionPane.showMessageDialog(this, "五子棋游戏测试版本", "关于", 0);
		if(arg.equals("退出"))
			System.exit(0);
	}
}

/*
 *类ChessModel实现了整个五子棋程序算法的核心
 */
class ChessModel {
	//棋盘的宽度、高度、棋盘的模式(如20×15)
	private int width,height,modeChess;
	//棋盘方格的横向、纵向坐标
	private int x=0,y=0;
	//棋盘方格的横向、纵向坐标所对应的棋子颜色,
	//数组arrMapShow只有3个值:1,2,3,-5,
	//其中1代表该棋盘方格上下的棋子为黑子,
	//2代表该棋盘方格上下的棋子为白子,
	//3代表为该棋盘方格上没有棋子,
	//-5代表该棋盘方格不能够下棋子
	private int[][] arrMapShow;
	//交换棋手的标识,棋盘方格上是否有棋子的标识符
	private boolean isOdd,isExist;

	public ChessModel() {}
	
	//该构造方法根据不同的棋盘模式(modeChess)来构建对应大小的棋盘
	public ChessModel(int modeChess){
		this.isOdd=true;
		if(modeChess == 1){
			PanelInit(20, 15, modeChess);
		}
		if(modeChess == 2){
			PanelInit(30, 20, modeChess);
		}
		if(modeChess == 3){
			PanelInit(40, 30, modeChess);
		}
	}
	
	//按照棋盘模式构建棋盘大小
	private void PanelInit(int width, int height, int modeChess){
		this.width = width;
		this.height = height;
		this.modeChess = modeChess;
		arrMapShow = new int[width+1][height+1];
		for(int i = 0; i <= width; i++){
			for(int j = 0; j <= height; j++){
				arrMapShow[i][j] = -5;
			}
		}
	}
	
	//获取是否交换棋手的标识符
	public boolean getisOdd(){
		return this.isOdd;
	}

	//设置交换棋手的标识符
	public void setisOdd(boolean isodd){
		if(isodd)
			this.isOdd=true;
		else
			this.isOdd=false;
	}
	
	//获取某棋盘方格是否有棋子的标识值
	public boolean getisExist(){
		return this.isExist;
	}
	
	//获取棋盘宽度
	public int getWidth(){
		return this.width;
	}
	
	//获取棋盘高度
	public int getHeight(){
		return this.height;
	}
	
	//获取棋盘模式
	public int getModeChess(){
		return this.modeChess;
	}

	//获取棋盘方格上棋子的信息
	public int[][] getarrMapShow(){
		return arrMapShow;
	}

	//判断下子的横向、纵向坐标是否越界
	private boolean badxy(int x, int y){
		if(x >= width+20 || x < 0)
			return true;
		return y >= height+20 || y < 0;
	}

	//计算棋盘上某一方格上八个方向棋子的最大值,
	//这八个方向分别是:左、右、上、下、左上、左下、右上、右下
	public boolean chessExist(int i,int j){
		if(this.arrMapShow[i][j]==1 || this.arrMapShow[i][j]==2)
			return true;
		return false;
	}

	//判断该坐标位置是否可下棋子
	public void readyplay(int x,int y){
		if(badxy(x,y))
			return;
		if (chessExist(x,y))
			return;
		this.arrMapShow[x][y]=3;
	}

	//在该坐标位置下棋子
	public void play(int x,int y){
		if(badxy(x,y))
			return;
		if(chessExist(x,y)){
			this.isExist=true;
			return;
		}else
			this.isExist=false;
		if(getisOdd()){
			setisOdd(false);
		this.arrMapShow[x][y]=1;
		}else{
			setisOdd(true);
			this.arrMapShow[x][y]=2;
		}
	}

	//计算机走棋
	/*
	 *说明:用穷举法判断每一个坐标点的四个方向的的最大棋子数,
	 *最后得出棋子数最大值的坐标,下子
	 **/
	public void computerDo(int width,int height){
		int max_black,max_white,max_temp,max=0;
		setisOdd(true);
		System.out.println("计算机走棋 ...");
		for(int i = 0; i <= width; i++){
			for(int j = 0; j <= height; j++){
				if(!chessExist(i,j)){//算法判断是否下子
					max_white=checkMax(i,j,2);//判断白子的最大值
					max_black=checkMax(i,j,1);//判断黑子的最大值
					max_temp=Math.max(max_white,max_black);
					if(max_temp>max){
						max=max_temp;
						this.x=i;
						this.y=j;
					}
				}
			}
		}
		setX(this.x);
		setY(this.y);
		this.arrMapShow[this.x][this.y]=2;
	}
	
	//记录电脑下子后的横向坐标
	public void setX(int x){
		this.x=x;
	}
	
	//记录电脑下子后的纵向坐标
	public void setY(int y){
		this.y=y;
	}
	
	//获取电脑下子的横向坐标
	public int getX(){
		return this.x;
	}
	
	//获取电脑下子的纵向坐标
	public int getY(){
		return this.y;
	}

	//计算棋盘上某一方格上八个方向棋子的最大值,
	//这八个方向分别是:左、右、上、下、左上、左下、右上、右下
	public int checkMax(int x, int y,int black_or_white){
		int num=0,max_num,max_temp=0;
		int x_temp=x,y_temp=y;
		int x_temp1=x_temp,y_temp1=y_temp;
		//judge right
		for(int i=1;i<5;i++){
			x_temp1+=1;
			if(x_temp1>this.width)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		//judge left
		x_temp1=x_temp;
		for(int i=1;i<5;i++){
			x_temp1-=1;
			if(x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		if(num<5)
			max_temp=num;

		//judge up
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=0;
		for(int i=1;i<5;i++){
			y_temp1-=1;
			if(y_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		//judge down
		y_temp1=y_temp;
		for(int i=1;i<5;i++){
			y_temp1+=1;
			if(y_temp1>this.height)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		if(num>max_temp&&num<5)
			max_temp=num;

		//judge left_up
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=0;
		for(int i=1;i<5;i++){
			x_temp1-=1;
			y_temp1-=1;
			if(y_temp1<0 || x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		//judge right_down
		x_temp1=x_temp;
		y_temp1=y_temp;
		for(int i=1;i<5;i++){
			x_temp1+=1;
			y_temp1+=1;
			if(y_temp1>this.height || x_temp1>this.width)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		if(num>max_temp&&num<5)
			max_temp=num;

		//judge right_up
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=0;
		for(int i=1;i<5;i++){
			x_temp1+=1;
			y_temp1-=1;
			if(y_temp1<0 || x_temp1>this.width)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		//judge left_down
		x_temp1=x_temp;
		y_temp1=y_temp;
		for(int i=1;i<5;i++){
			x_temp1-=1;
			y_temp1+=1;
			if(y_temp1>this.height || x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==black_or_white)
				num++;
			else
				break;
		}
		if(num>max_temp&&num<5)
			max_temp=num;
		max_num=max_temp;
		return max_num;
	}

	//判断胜负
	public boolean judgeSuccess(int x,int y,boolean isodd){
		int num=1;
		int arrvalue;
		int x_temp=x,y_temp=y;
		if(isodd)
			arrvalue=2;
		else
			arrvalue=1;
		int x_temp1=x_temp,y_temp1=y_temp;
		//判断右边
		for(int i=1;i<6;i++){
			x_temp1+=1;
			if(x_temp1>this.width)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		//判断左边
		x_temp1=x_temp;
		for(int i=1;i<6;i++){
			x_temp1-=1;
			if(x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		if(num==5)
			return true;

		//判断上方
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=1;
		for(int i=1;i<6;i++){
			y_temp1-=1;
			if(y_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		//判断下方
		y_temp1=y_temp;
		for(int i=1;i<6;i++){
			y_temp1+=1;
			if(y_temp1>this.height)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		if(num==5)
			return true;

		//判断左上
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=1;
		for(int i=1;i<6;i++){
			x_temp1-=1;
			y_temp1-=1;
			if(y_temp1<0 || x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		//判断右下
		x_temp1=x_temp;
		y_temp1=y_temp;
		for(int i=1;i<6;i++){
		x_temp1+=1;
		y_temp1+=1;
		if(y_temp1>this.height || x_temp1>this.width)
			break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		if(num==5)
			return true;

		//判断右上
		x_temp1=x_temp;
		y_temp1=y_temp;
		num=1;
		for(int i=1;i<6;i++){
			x_temp1+=1;
			y_temp1-=1;
			if(y_temp1<0 || x_temp1>this.width)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		//判断左下
		x_temp1=x_temp;
		y_temp1=y_temp;
		for(int i=1;i<6;i++){
			x_temp1-=1;
			y_temp1+=1;
			if(y_temp1>this.height || x_temp1<0)
				break;
			if(this.arrMapShow[x_temp1][y_temp1]==arrvalue)
				num++;
			else
				break;
		}
		if(num==5)
			return true;
		return false;
	}

	//赢棋后的提示
	public void showSuccess(JPanel jp){
		JOptionPane.showMessageDialog(jp,"你赢了,好厉害!","win",
			JOptionPane.INFORMATION_MESSAGE);
	}
	
	//输棋后的提示
	public void showDefeat(JPanel jp){
		JOptionPane.showMessageDialog(jp,"你输了,请重新开始!","lost",
			JOptionPane.INFORMATION_MESSAGE);
	}
}

/*
 *类MainPanel主要完成如下功能:
 *1、构建一个面板,在该面板上画上棋盘;
 *2、处理在该棋盘上的鼠标事件(如鼠标左键点击、鼠标右键点击、鼠标拖动等)
 **/
class MainPanel extends JPanel 
	implements MouseListener,MouseMotionListener{
	private int width,height;//棋盘的宽度和高度
	private ChessModel cm;
	
	//根据棋盘模式设定面板的大小
	MainPanel(ChessModel mm){
		cm=mm;
		width=cm.getWidth();
		height=cm.getHeight();
		addMouseListener(this);
	}
    
    //根据棋盘模式设定棋盘的宽度和高度
	public void setModel(ChessModel mm){
		cm = mm;
		width = cm.getWidth();
		height = cm.getHeight();
	}

	//根据坐标计算出棋盘方格棋子的信息(如白子还是黑子),
	//然后调用draw方法在棋盘上画出相应的棋子
	public void paintComponent(Graphics g){
		super.paintComponent(g);
		for(int j = 0; j <= height; j++){
			for(int i = 0; i <= width; i++){
				int v = cm.getarrMapShow()[i][j];
				draw(g, i, j, v);
			}
		}
	}

	//根据提供的棋子信息(颜色、坐标)画棋子
	public void draw(Graphics g, int i, int j, int v){
		int x = 20 * i+20;
		int y = 20 * j+20;
		//画棋盘
		if(i!=width && j!=height){
			g.setColor(Color.white);
			g.drawRect(x,y,20,20);
		}
		//画黑色棋子
		if(v == 1 ){
			g.setColor(Color.gray);
			g.drawOval(x-8,y-8,16,16);
			g.setColor(Color.black);
			g.fillOval(x-8,y-8,16,16);
		}
		//画白色棋子
		if(v == 2 ){
			g.setColor(Color.gray);
			g.drawOval(x-8,y-8,16,16);
			g.setColor(Color.white);
			g.fillOval(x-8,y-8,16,16);
		}
		if(v ==3){
			g.setColor(Color.cyan);
			g.drawOval(x-8,y-8,16,16);
		}
	}

	//响应鼠标的点击事件,根据鼠标的点击来下棋,
	//根据下棋判断胜负等
	public void mousePressed(MouseEvent evt){
		int x = (evt.getX()-10) / 20;
		int y = (evt.getY()-10) / 20;
		System.out.println(x+" "+y);
		if (evt.getModifiers()==MouseEvent.BUTTON1_MASK){
			cm.play(x,y);
			System.out.println(cm.getisOdd()+" "+cm.getarrMapShow()[x][y]);
			repaint();
			if(cm.judgeSuccess(x,y,cm.getisOdd())){
				cm.showSuccess(this);
				evt.consume();
				ChessFrame.iscomputer=false;
			}
			//判断是否为人机对弈
			if(ChessFrame.iscomputer&&!cm.getisExist()){
				cm.computerDo(cm.getWidth(),cm.getHeight());
				repaint();
				if(cm.judgeSuccess(cm.getX(),cm.getY(),cm.getisOdd())){
					cm.showDefeat(this);
					evt.consume();
				}
			}
		}
	}

	public void mouseClicked(MouseEvent evt){}
	public void mouseReleased(MouseEvent evt){}
	public void mouseEntered(MouseEvent mouseevt){}
	public void mouseExited(MouseEvent mouseevent){}
	public void mouseDragged(MouseEvent evt){}
    
    //响应鼠标的拖动事件
	public void mouseMoved(MouseEvent moveevt){
		int x = (moveevt.getX()-10) / 20;
		int y = (moveevt.getY()-10) / 20;
		cm.readyplay(x,y);
		repaint();
	} 
}

class ChessWindowEvent extends WindowAdapter{
	public void windowClosing(WindowEvent e){
		System.exit(0);
	}

	ChessWindowEvent(){}
}