还有我老是给批说做事三分钟热度。不能够坚持。然后还被说这样子神马事情都做不成,感觉这个好,就做这个,后来发现遇到坎了,然后又动手做其他的。像之前的扫雷,做了一些感觉界面出不来,又换连连看。这个缺点真的是死穴,希望以后不管谁都不要学我。其实他说的很有道理,做一件事情多想想为什么,把事情的本质原理搞懂了以后实现起来就知道怎么做了。或许第一次很慢,但是到了第二次做同一件事情速度绝对会比别人快而且理解的更加深刻。
OK,屁事唠叨完了。开始讲讲这几个月学的一些东西。
先是画图板。
Swing组件的一些东西想知道用法就翻jdk1.6 API。
其实画板学到最多的是一个名次耦合度(虽然这个名次是别人告诉我的),先说下布局,从菜单,到左边的工具条,再到底下的工具条,还有中间的面板。一个部分是一个单独的控件,在主函数中调用,之间的联系靠传参,这样就大大提高代码的重用性。
连连看主要是算法。
有判断是水平的,竖直的,一个弯的,两个弯的。还有边界,当时做边界的时候是很头疼的,后来想想,我们用二维数组来放图片,然后边界的话,不就是在外面再扩大一个圈,其实这个是一个很重要的思想。水平的和竖直的其实很简单,判断之间有没有障碍物就可以了。一个弯的话。可以这两个点的另一条对角线的两个点,判断这两个点和原来两个点之间有没有障碍物,只要符合一种就行了。至于那个坑爹的两个弯的,转化一下思想,其实可以这样,先从上找,两个点中比较比较矮的一个点,向上遍历,直到碰到障碍物停止遍历,然后判断遍历到的点和另一个点能否一个弯连起来。再其他方向也遍历一遍。好像讲的有点抽象。
在此附上代码一小段
// 向上搜索的情况一
if (r1 <= r2) {
for (int i = r2 - 1; i >= 0; i--) {
if (cu.CHESS[i][c2] == 0) {
if (Judge.JudgeOneGuai(r1, c1, i, c2, cu)) {
point5=new Point(i,c2);
point6=new Point(r2,c2);
list.add(point5);
list.add(point6);
return true;
}
} else {
break;
}
}
}
接着就是对于文件的一些操作。
File包括文件夹,文件,还有虚拟内存文件。
File中比较常见的方法:
boolean exists(); 返回这个文件是否存在
String getName();返回该路径下的文件名
File getAbsoluteFile();返回该文件。
File getAbsolutePath();返回该文件的绝对路径。
boolean isDirectory();返回该文件是否为一个目录。
File.listRoots() ;列出系统的根文件夹。
通过以上的一些方法就可以统计在你规定的路径中包含多少的文件了。
File[]files=file.listFiles();
//如果返回的是NULL,表示file不是一个文件夹
if(files==null){
return;
}
for(int i=0;i<files.length;i++){
File f=files[i];
String str=f.getAbsolutePath();
//如果是一个标准文件
if(f.isFile()){
countfile++;
}
//如果是一个文件夹就递归调用
else if(f.isDirectory()){
countFile(str);
}
}
然后就是创建一个输入输出流来传输文件内容了。
内存中的数据写到硬盘中的话用FileOutputStream,相应的另一种用FileInputStream.
但是会发现这样的话大点的文件速度就相当的慢,FileOutputStream和FileInputStream其实是在缓冲区读一个字节写一个字节,因此我们可以换一种BufferedInputStream, 为FileInputStream输入流添加一些功能,能够在缓冲区多读一些字节,然后再进行传输。那这样速度不就快很多了么。
但是就像水龙头一样开了以后一定要关,所以在用完以后一定要记得对象.close();还要注意的是输出流的话,因为内存写出的速度比硬盘读取的速度要快很多,因此一定还要记得输出流对象.flush,把管道里面的字节全部输出,然后再close。
再讲一下BMP的读取。首先了解一下位运算符。
| :按位或 比如 0000 0101 | 1110 1001 每一位取大的一个数,结果就是 1110 1101
& :按位与 比如 0000 0101 & 1110 1001 每一位取小的一个数, 结果就是0000 0001
>> :右移 比如 0000 1010<<1 每位往右移一位,左端补0其实也就是将他转化成ASCII码以后再除以2. 结果就会是 0000 0101
<< :左移 比如 0000 1010>>2 每位往左移一位,右端补0其实也就是将他转化成ASCII码以后再乘以2*2. 结果就会是 0010 1000
然后就是BMP的我存储结构。
第一部分是位图头文件 14个字节固定
第二部分是位图信息头:
image_width:4-7;image-height:8-11; 一个像素需要的位数BibitCount:14-15;
位图大小 Image_size:20-23
可以通过计算获得每一行补零的字节数
第三部分是 调色板 如果是二十四位图,那么调色板这部分就不存在。
第四部分就是实际的位图信息了。
读取这部分的时候要注意三个点:
1、位图的写入是从下到上,从左到右,所以读取的时候一定要小心。
2、位图颜色读取的时候是BGR,即使倒着写的。
3、写入的时候每行的字节数都是4的倍数。但是每个点的颜色存储只需要三个字节。不够的要补零,所以要通过第二部分的一些信息来计算补零个数,再跳过。
//计算需要补齐的字节数
if(!(image_width*3%4==0)){
skip_width=4-image_width*3%4;
}
System.out.println(image_height+"<<<<"+image_width);
Red=new int [image_height][image_width];
Green=new int [image_height][image_width];
Blue=new int [image_height][image_width];
//将读取的RGB存入,注意是从下到上读入,并且补0是在一行的末端,所以读取顺序是蓝绿红
for(int i=image_height-1;i>=0;i--){
for(int j=0;j<image_width;j++){
Blue[i][j]=dis.read();
Green[i][j]=dis.read();
Red[i][j]=dis.read();
if(j==image_width-1){
System.out.println(dis.skipBytes(skip_width));
}
}
}
OK,BMP就可以打开了。