您的位置:首页 > 编程语言 > Java开发

最近都在纠结走迷宫啊~~java走迷宫,会回滚的走迷宫。。。

2014-05-13 22:25 288 查看
说是走迷宫其实就是之前打印字,然后把白色的都走遍,有木有?

纠结就纠结在怎么把标准输出显示在jTextArea中,这个,先卖关子,看完源代码和解释之后再和你们说,说不定你们看完源代码就自己就会了,什么重定向转发的都弱爆了!

废话不多说,来上源代码:

因为在培养我们的MVC模式,所以明明一个源代码可以搞掂的,被拆分成了三个:分别是model、control和view,其中view是用netbeans自动生成的Jframe文件,netbeans就是我心中的痛,每次开都要半小时啊,有木有?

有解决办法的亲,告诉一下我怎么解决呗!一直就卡在“正在启动模块...”

首先是Model层的代码(解释照样是写在源代码中,顺着看,还可以熟悉代码...)

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package maze;

import java.io.PrintStream;

/**
* 这就是模型层,只要是实现的功能,都在这里能找到
*
* @author Janeness
*/
public class Name {

int x1 = 1; //设置运行的初始位置的x为1
int y1 = 1;    //初始的y位置为1
final String s1 = " □ ";
//这里是定义你需要的字符串,一个为空心方,一个是实心方
final String s2 = " ■ ";
final String roolback = " @ ";
//回滚的符号
final int x = 40;
//这里定义的是行数和列数,用来实现对应的字符的排列
final int y = 40;
String a[][] = new String[x][y];
//这里就是正式定义数组,数组的大小就通过上面的x和y决定
final String down = " ↓ ";
final String up = " ↑ ";
final String left = " ←";
final String right = " →";
//分别对应向下、向上、向左、向右走
PrintStream ps = new PrintStream(System.out);
//用来实验重定向,没有成功,留着也没事,以后记起来再做也能行

//-------------------------设置笔画----------------------------------------------
private void setE() {
//用来初始化所有的数组元素为空心方
//值得注意的是,一般都是i在外围,j在内围,但是为了元素的不变,必须i在里面
//因为最里面每次循环的是一行,一行中,只有y不变,x一直在变
for (int j = 0; j < y; j++) {
for (int i = 0; i < x; i++) {
a[i][j] = s1;
//初始化整个图形,为二维数组的每个元素进行设值
}
}
}

private void setB() {
//用来设置边框,把四条边都变成实心方
for (int i = 0; i < a.length; i++) {
a[i][0] = s2;
//四条边都是设置成s2也就是实心方
a[i][a.length - 1] = s2;
a[0][i] = s2;
a[a.length - 1][i] = s2;
}
}

private void setX(int y, int beginX, int endX) {
//这个是用来画一横
for (int i = beginX - 1; i < endX - 1; i++) {
//y轴不变,x有范围,提供起始的x和结束的x就可以画一横了
a[i][y - 1] = s2;
}
}

private void setY(int x, int beginY, int endY) {//这个是用来画一竖
for (int i = beginY - 1; i < endY - 1; i++) {
//x轴不变,y有范围,提供起始的y和结束的y就可以画一横了
a[x - 1][i] = s2;
}
}

private void setW(int x, int y) {//这个是用来画一撇
for (int i = x; i < x + 3; i++) {
a[i][y] = s2;
//因为撇和捺从左往右x都是增加的,有区别的就是y轴
//撇从左往右y是减少的,所以y--;
y--;
}
}

private void setV(int x, int y) {
for (int i = x; i < x + 3; i++) {
a[i][y] = s2;
//而这个从左往右y是增加的,所以y++;
y++;
}
}

//---------------------设置名字笔画-------------------------------------------------
public void printName() {
// TODO code application logic here
//创建一个封装好的类的对象来调用
setE();
setB();
//初始化对象,并且画出边框
setX(6, 4, 17);
setY(4, 12, 34);
setX(12, 4, 16);
setY(16, 12, 34);
setY(8, 7, 24);
setY(11, 7, 24);
setX(24, 5, 9);
setX(24, 11, 17);
setX(29, 5, 16);
setX(34, 4, 17);
//画出左边的偏旁
setY(23, 6, 12);
setW(19, 13);
setX(10, 23, 37);
setX(18, 19, 38);
setY(29, 6, 18);
//画出右边的上面部分
setX(22, 20, 37);
setX(34, 20, 37);
setY(20, 22, 35);
setY(37, 22, 35);
//画出右边的下面部分
printOut();
//调用打印方法,打印出我们的二维数组对象
//        view.jTextArea1.setText(ps.toString());同样是测试用的

}
//---------------------------打印出来(测试)---------------------------------------

public String printOut() {
String str = "";
//这里是输出这个数组,因为是一行一行的输出,所以x的循环再里面,先循环
for (int j = 0; j < y; j++) {
//这个是y的循环,在x循环完一次之后,y加1
for (int i = 0; i < x; i++) {
//在y每加1的时候,循环一整个x的元素
str += a[i][j];
//把循环的值都赋值给str
}
str += "\n";
//让str加上 "\n",这样可以实现jTextArea显示的换行
}
return str;
//返回一个String,赋值给jTextArea
}

//---------------------------------------------------------------------------------
public void moving() {
if (a[x1][y1 + 1].equals(s1)) {
down();
//如果下面一格是白色,向下走
} else if (a[x1 + 1][y1].equals(s1)) {
right();
//如果右边一格式白色,向右走
} else if (a[x1][y1 - 1].equals(s1)) {
up();
//如果上边一格式白色,向上走
} else if (a[x1 - 1][y1].equals(s1)) {
left();
//如果左边一格式白色,向左走
} else {
roolback();
//回滚,走法和上一步的方向相反
}
}
//------------------------上下左右的方法--------------------------------------------
private void down() {
a[x1][y1] = down;
y1++;
}

private void up() {
a[x1][y1] = up;
y1--;
}

private void left() {
a[x1][y1] = left;
x1--;
}

private void right() {
a[x1][y1] = right;
x1++;
}

private void roolback() {
a[x1][y1] = roolback;
if (a[x1][y1 - 1].equals(down)) {
//如果上面一格是向下,那么向上走
y1--;
} else if (a[x1][y1 + 1].equals(up)) {
//如果下面一格是向上,那么向下走
y1++;
} else if (a[x1 - 1][y1].equals(right)) {
//如果左边一格是向右,那么向左走
x1--;
} else if (a[x1 + 1][y1].equals(left)) {
//如果右边一格是向左,那么向右走
x1++;
}
}
}
下面是Control中的源代码:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package maze;

/**
*
* @author Janeness
*/
public class Control extends Thread {

Name model = new Name();
//在这里定义model并创建实例
View v;
//这里只用声明,如果创建实例的话,会出此案初始化错误
//因为在view中也有创建control实例

public Control(View v) {
this.v = v;
//初始化的时候把view的值赋值给control,指定view为当前的view
//而不是新创建并实例化的任何其他view
}

public void printLn() {
model.printName();
//调用model中的打印图片的方法进行打印
v.jTextArea1.setText(model.printOut());
//对view中的jTextArea进行赋值,才能显示出打印的图片
}

@Override
public void run() {//调用thread的start()方法时,执行control线程
while (!(model.a.equals("#"))) {
//设置终点为该数组元素等于字符串"#",因为没设置,所以默认是走到a[1][1]就不走了
try {
model.moving();
//实现走动方法,不到终点就一直运行
Thread.sleep(100);
//继承自thread,所以没走一步,休眠100毫秒
//这里要对线程进行异常的捕获
v.jTextArea1.setText(model.printOut());
//修改之后,打印出修改之后的图片
} catch (InterruptedException ex) {
}
}

}
}
最后是view层的源代码:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package maze;

/**
*
* @author Janeness
*/
public class View extends javax.swing.JFrame {
Control control=new Control(this);
//创建并实例化control类,并把当前的view复制给在control类中声明的view

/**
* Creates new form View
*/
public View() {
initComponents();
}

/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jScrollPane1 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane1.setViewportView(jTextArea1);

jButton1.setText("打印图案");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
PrintPicture(evt);
}
});

jButton2.setText("开始运行");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 633, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton1)
.addComponent(jButton2))
.addGap(27, 27, 27))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGap(118, 118, 118)
.addComponent(jButton1)
.addGap(75, 75, 75)
.addComponent(jButton2)
.addContainerGap(295, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

private void PrintPicture(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
control.printLn();//实现打印名字方法
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
control.start();//启动线程
}

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(View.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(View.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(View.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(View.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>

/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new View().setVisible(true);
}
});
}
// Variables declaration - do not modify
public javax.swing.JButton jButton1;
public javax.swing.JButton jButton2;
public javax.swing.JScrollPane jScrollPane1;
public javax.swing.JTextArea jTextArea1;
// End of variables declaration
//在这里,如果jScrollPane1和jTextArea1不是public修饰的话
//那么要设置到为public的才行,要不control无法调用该属性
}


其实关键的是control的实现和使用,大部分代码都没什么用,在创建jFrame的时候就已经生成了那些代码,所以,也就不去深究了,有时间再深究。

对了,标准输出要在jTextArea输出的代码就是,创建一个返回值为String类型的方法,遍历出String二位数组,然后给jTextArea赋值就可以了,详细代码:

public String printOut() {
String str = "";
//这里是输出这个数组,因为是一行一行的输出,所以x的循环再里面,先循环
for (int j = 0; j < y; j++) {
//这个是y的循环,在x循环完一次之后,y加1
for (int i = 0; i < x; i++) {
//在y每加1的时候,循环一整个x的元素
str += a[i][j];
//把循环的值都赋值给str
}
str += "\n";
//让str加上 "\n",这样可以实现jTextArea显示的换行
}
return str;
//返回一个String,赋值给jTextArea
}
这样就简单的解决了,我绞尽脑汁辛苦那么久都没有做出来的功能了!

好了,下次分析其他代码

现在在做简易俄罗斯方块,所以,下次的blog也许就是俄罗斯方块的讲解了!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: