天天看点

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

说是走迷宫其实就是之前打印字,然后把白色的都走遍,有木有?

纠结就纠结在怎么把标准输出显示在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也许就是俄罗斯方块的讲解了!!!