如何更新标签的迷宫网格以显示解算器所采用的路径(突出显示所采用的路径)

时间:2014-03-15 04:00:59

标签: java swing jlabel mouselistener maze

我和一个合作伙伴被分配了一个项目,我们必须创建一个GUI,实现一个JLabel网格,可以点击它来创建一个迷宫的墙壁,并实现一个求解器类,通过点击一个解决所述迷宫解决按钮。我们有求解器和GUI一起工作,但我们遇到麻烦的是在解决后尝试更新GUI。我们知道它正确地解决了迷宫问题,因为我们打印了一个解决方案的数组但是我们的生活中不知道如何更新GUI以突出显示单击求解按钮的求解器的路径。有没有办法做到这一点?

解算器类:

package lab8;

import java.util.ArrayList;

public class Solver implements MazeSolver {

    private static ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();

    public Solver() {

    }

    @Override
    public String[][] solve(String[][] map) {

        String[][] str =

        new String[map.length][map[0].length];

        boolean done = false;

        for (int row = 0; row < map.length; row++) {

            for (int col = 0; col < map[0].length; col++) {

                str[row][col] = map[row][col];

            }

        }

        Coordinate c1 = findStart(str);

        Coordinate c2 = findFinish(str);

        int x = 0;

        while (done == false) {

            if ((c1.getRow() + 1 == c2.getRow()) && c1.getCol() == c2.getCol()) {
                str[c2.getRow()][c2.getCol()] = "RIP";
                break;

            }

            if (isClear(str, c1.getRow() + 1, c1.getCol())) {

                str[c1.getRow() + 1][c1.getCol()] = "X";
                c1 = new Coordinate(c1.getRow() + 1, c1.getCol());
                coordinates.add(c1);
            } else if (isClear(str, c1.getRow(), c1.getCol() + 1)) {
                str[c1.getRow()][c1.getCol() + 1] = "X";
                c1 = new Coordinate(c1.getRow(), c1.getCol() + 1);
                coordinates.add(c1);
            } else if (isClear(str, c1.getRow(), c1.getCol() - 1)) {
                str[c1.getRow()][c1.getCol() - 1] = "X";
                c1 = new Coordinate(c1.getRow(), c1.getCol() - 1);
                coordinates.add(c1);
            } else if (isClear(str, c1.getRow() - 1, c1.getCol())) {
                str[c1.getRow() - 1][c1.getCol()] = "X";
                c1 = new Coordinate(c1.getRow() - 1, c1.getCol());
                coordinates.add(c1);
            }
            if ((str[c1.getRow() - 1][c1.getCol()].equals("X")
                    || str[c1.getRow() - 1][c1.getCol()].equals("W") || str[c1
                    .getRow() - 1][c1.getCol()].equals("D"))
                    && (str[c1.getRow() + 1][c1.getCol()].equals("X")
                            || str[c1.getRow() + 1][c1.getCol()].equals("W") || str[c1
                            .getRow() + 1][c1.getCol()].equals("D"))
                    && (str[c1.getRow()][c1.getCol() - 1].equals("X")
                            || str[c1.getRow()][c1.getCol() - 1].equals("W") || str[c1
                                .getRow()][c1.getCol() - 1].equals("D"))
                    && (str[c1.getRow()][c1.getCol() + 1].equals("X")
                            || str[c1.getRow()][c1.getCol() + 1].equals("W") || str[c1
                                .getRow()][c1.getCol() + 1].equals("D"))) {

                str[c1.getRow()][c1.getCol()] = "D";
                coordinates.remove(coordinates.size() - 1);
                c1 = coordinates.get(coordinates.size() - 1);
            }
            x++;
            if(x >= 300) {
                c1 = findStart(map);
                break;
            }
        }
        return str;
    }

    public Coordinate findStart(String[][] map) {
        Coordinate start = new Coordinate(0, 0);
        for (int row = 0; row < map.length; row++) {
            for (int col = 0; col < map[0].length; col++) {
                if (map[row][col].equals("S")) {
                    start = new Coordinate(row, col);
                }
            }
        }
        return start;
    }

    public Coordinate findFinish(String[][] map) {
        Coordinate finish = new Coordinate(0, 0);
        for (int row = 0; row < map.length; row++) {
            for (int col = 0; col < map[0].length; col++) {
                if (map[row][col].equals("F")) {
                    finish = new Coordinate(row, col);
                }
            }
        }
        return finish;
    }

    public boolean isClear(String[][] map, int x, int y) {
        if (x >= map.length) {
            return false;
        }
        if (x >= map[0].length) {
            return false;
        }
        if (map[x][y].equals("S")) {
            return false;
        }
        if (map[x][y].equals("D")) {
            return false;
        }
        if (map[x][y].equals("W")) {
            return false;
        }
        return true;
    }

    public static void main(String[] args) {
        Solver s1 = new Solver();

        String[][] map = {
                { "W", "S", "W", "W", "W", "W", "W", "W", "W", "" , "W"},
                { "W", "", "W", "", "", "", "", "", "", "" , "W"},
                { "W", "", "W", "", "W", "W", "W", "W", "", "", "W" },
                { "W", "", "W", "", "W", "", "W", "W", "", "" , "W"},
                { "W", "", "W", "", "W", "W", "", "W", "", "", "W" },
                { "W", "", "W", "", "W", "", "", "W", "", "" , "W"},
                { "W", "", "W", "", "", "", "W", "W", "", "" , "W"},
                { "W", "", "W", "", "W", "W", "W", "W", "", "" , "W"},
                { "W", "", "", "", "W", "", "", "", "", "" , "W"},
                { "W", "W", "W", "W", "W", "W", "W", "W", "W", "F" , "W"} };
        for (int i = 0; i < s1.solve(map).length; i++) {
            for (int j = 0; j < s1.solve(map)[0].length; j++) {
                System.out.printf("%3s", s1.solve(map)[i][j]);
            }
            System.out.println();
        }
    }
}

协调班级

    package lab8;

public class Coordinate {

    private int row;
    private int col;

    public Coordinate(int row, int col) {
        this.row = row;
        this.col = col;
    }

    public int getRow() {
        return row;
    }

    public int getCol() {
        return col;
    }
     public String toString() {
            return "Coordinate [row=" + row + ", col=" + col + "]";
        }

}

合作伙伴的GUI类

    package lab8;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

 import javax.swing.*;

public class MazeGUI {
    String[][] map = new String[12][12];
    JPanel labelPanel,startPanel;
    JLabel labs;


    private void createMaze() {
        // creates the maze
        JFrame frame = new JFrame("Zombie Run");
         frame.setLayout(new BorderLayout());
        final JPanel labelPanel = new JPanel();
        labelPanel.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
        labelPanel.setLayout(new GridLayout(12, 12));

        for (int row = 0; row < 12; row++) {
            for (int cols = 0; cols < 12; cols++) {
                final int i = row;
                final int j = cols;
                final JLabel labs = new JLabel();

                // create and set the labels
                labs.setSize(new Dimension(50, 50));
                labs.setBorder(BorderFactory.createLineBorder(Color.blue));

                labs.setBackground(Color.black);
                map[row][cols]="";


                mapArray(row, cols, labs);
                labs.addMouseListener(new MouseListener() {
                    boolean clicked = false;

                    @Override
                    public void mouseClicked(MouseEvent arg0) {
                         // the color changes when clicked

                        if (clicked == true) {
                            clicked = false;
                            labs.setBackground(Color.black);
                             map[i][j] = "";

                        }
                        else {
                            clicked = true;
                            labs.setBackground(Color.cyan);
                             map[i][j] = "W";

                        }

                    }

                    @Override
                    public void mouseEntered(MouseEvent e) {
                         // TODO Auto-generated method stub

                    }

                    @Override
                    public void mouseExited(MouseEvent e) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void mousePressed(MouseEvent e) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void mouseReleased(MouseEvent e) {
                        // TODO Auto-generated method stub

                    }
                });
                if(map[i][j].equals("X") || map[i][j].equals("D")){
                    labs.setBackground(Color.RED);
                }

                if(row==0 || row==11){
                     labs.setBackground(Color.cyan);
                    map[row][cols]="W";
                }

                if(cols==0 || cols==11){
                    labs.setBackground(Color.cyan);
                   map[row][cols]="W";
               }

                if(row==0 && cols==1){
                    labs.setBackground(Color.black);
                     map[row][cols]="S";
                }
                if(row==11 && cols==10){
                    labs.setBackground(Color.black);
                    map[row][cols]="F";
                 }
                labs.setOpaque(true);
                labelPanel.add(labs);

            }

        }

        startPanel = new JPanel();
        JButton runMaze = new JButton("Feed the Zombie");
         runMaze.addActionListener(new ActionListener() {
            boolean clicked = false;

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // Makes the zombie find the brain
                 if (clicked == false) {
                    clicked = true;
                    Solver solver;
                    solver= new Solver();
                    solver.solve(map);
                    for(int i = 0; i < map.length; i++){
                        for(int j = 0; j < map[0].length; j++){
                            System.out.printf("%3s", solver.solve(map)[i][j]);
                        }
                        System.out.println();
                    }
                 }

            }
        });
        runMaze.setBackground(Color.green);
        startPanel.add(runMaze);
        runMaze.add(labelPanel);
        frame.add(labelPanel, BorderLayout.NORTH);
         frame.add(startPanel, BorderLayout.SOUTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        for(int i = 0; i < map.length; i++){
            for(int j = 0; j < map[0].length; j++){
                System.out.printf("%3s", map[i][j]);
            }
            System.out.println();
        }
    }

    private void mapArray(int row, int cols, JLabel labs) {
         // checks the space and inserts string

        if (row == 0 || row == 11) {
            map[row][cols] = "W";
            map[row][cols] = "W";
        }
        if (cols == 0 || cols == 11) {
             map[row][cols] = "W";
            map[row][cols] = "W";
        }
        if (row == 0 && cols == 1) {
            map[0][1] = "S";
            labs.setText("Start");
         }
        if (row == 11 && cols == 10) {
            map[row][10] = "F";
            labs.setText("End");
        } else {
            map[row][cols] = "";
        }        
     }

    public static void main(String[] args) {
        // runs the program
        MazeGUI c = new MazeGUI();
        c.createMaze();
    }
};

1 个答案:

答案 0 :(得分:0)

一种简单直接的方法是以与迷宫本身相同的方式存储标签 - 即,作为实例变量(在这种情况下是标签数组)。

大致相同:

public class MazeGUI {
    String[][] map = new String[12][12];
    JLabel[][] labels = new JLabel[12][12]; // -----------  Add this
    ...

    private void createMaze() {
        ...
        for (int row = 0; row < 12; row++) {
            for (int cols = 0; cols < 12; cols++) {
                final int i = row;
                final int j = cols;
                final JLabel labs = new JLabel();

                labels[row][cols] = labs; // ----------- Store it here
                ...
            }
            ...
        }
        ...
    }

    // After the solution has been found, apply it to the labels roughly (!) like this:
    private void applySolutionToLabels(String solution[][]) {
        for (int row = 0; row < 12; row++) {
            for (int cols = 0; cols < 12; cols++) {
                labels[row][cols].setText(solution[rows][cols]); 
            }
        }
    }

但请注意,您的代码存在一些问题。 (这是“这是一团糟”的礼貌形式)

  • 应该从事件派发线程
  • 创建GUI
  • 您应该避免使用固定大小的数组和所有大小常量。如果你想将迷宫的大小从12x12改为13x13怎么办?想象一下你现在需要改变多少个地方。你应该至少(!)创建两个变量int mazeSizeX=12int mazeSizeY=12并在任何地方使用它们而不是常量12,以便以后可以轻松地更改
  • 您可以延长MouseAdapter而非实施MouseListener。那么你将不需要所有空方法
  • 你应该避免使用大的嵌套深度和“内联”匿名内部类,其中包含大量(深层嵌套)代码。考虑将一些代码提取到方法
  • coordinates列表不应该是静态的。相反,请使用private List<Coordinate> coordinates = ...
  • if - 陈述的一些进一步(次要)简化,但是人们必须明白他们正在做什么才能给出深刻的建议