GUI:突出它迷宫的路径?

时间:2014-03-12 23:32:12

标签: java swing user-interface actionlistener jlabel

我正在合作项目,我的合作伙伴为游戏创建了一个解算器类,而我的部分是创建MazeGUI。

当你单击Solve JButton时,它应该突出显示它在GUI本身上所采用的路径,但它只突出显示它“结束”的位置,这是最右下角不应该因为它是“W”而可以访问。如果有解决方案,“F”将变为“RIP”,如果迷宫没有解决方案,则应该有JLabel表示迷宫无法解析。

如何在ActionListener下的代码中为solveButton输入所有这些?

import java.awt.BorderLayout;
import java.awt.Color;
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.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class MazeGUI {
    String appName = "Zombie Attack!";
    JLabel appNameLabel;

    private JFrame frame;
    private JPanel buttonPanel, solvePanel;
    private JButton solveButton;
    // private JLabel noSolutionLabel;

    private final int rowCount = 10;
    private final int colCount = 10;
    private final int startRow = 0;
    private final int startCol = 1;
    private final int endRow = rowCount - 1;
    private final int endCol = colCount - 2;

    String[][] map;

    private void createAndShowGui() {
        frame = new JFrame("Zombie Attack!");

        solveButton = new JButton("Solve");

        map = new String[rowCount][colCount];
        buttonPanel = new JPanel();

        buttonPanel.setLayout(new GridLayout(rowCount, colCount, 2, 2));

        appNameLabel = new JLabel(appName);
        for (int rows = 0; rows < rowCount; rows++) {
            for (int columns = 0; columns < colCount; columns++) {

                map[rows][columns] = " ";

                final JLabel jlabel = new JLabel("");
                jlabel.setBackground(Color.BLACK);

                if (rows == startRow && columns == startCol) {
                    jlabel.setBackground(Color.BLACK);
                    jlabel.setForeground(Color.MAGENTA);
                    jlabel.setText("S");
                    map[startRow][startCol] = "S";
                }

                if (rows == endRow && columns == endCol) {
                    jlabel.setBackground(Color.BLACK);
                    jlabel.setForeground(Color.MAGENTA);
                    jlabel.setText("F");
                    map[endRow][endCol] = "F";
                }

                if (!(rows == startRow && columns == startCol || rows == endRow
                        && columns == endCol)) {
                    if (rows == 0 || rows == rowCount - 1 || columns == 0
                            || columns == colCount - 1) {
                        jlabel.setBackground(Color.LIGHT_GRAY);
                        map[rows][columns] = "W";
                    }
                }


                final int rc = rows;
                final int cc = columns;


                jlabel.addMouseListener(new MouseListener() {
                    boolean clicked = false;

                    @Override
                    public void mouseClicked(MouseEvent e) {
                        if (clicked == false) {
                            clicked = true;
                            jlabel.setBackground(Color.LIGHT_GRAY);
                            map[rc][cc] = "W";


                        } else {
                            clicked = false;
                            jlabel.setBackground(Color.BLACK);
                            map[rc][cc] = "";

                        }
                    }

                    @Override
                    public void mouseEntered(MouseEvent e) {
                    }

                    @Override
                    public void mouseExited(MouseEvent e) {
                    }

                    @Override
                    public void mousePressed(MouseEvent e) {
                    }

                    @Override
                    public void mouseReleased(MouseEvent e) {
                    }

                });

                solveButton.addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent event) {

                        MazeSolver solver;
                        solver = new MyMazeSolver();
                        solver.solve(map);
                        jlabel.setBackground(Color.RED);
                        jlabel.setForeground(Color.GREEN);
                        jlabel.setText("RIP");

                        for (int i = 0; i < map.length; i++){
                            for (int j = 0; j < map[0].length; j++){
                                System.out.print(map[i][j] + " ");
                            }
                            System.out.println();
                        }
                    }
                });
                System.out.print(map[rows][columns] + " ");
                buttonPanel.add(jlabel);

                jlabel.setOpaque(true);
            }
            System.out.println();
        }
        frame.add(appNameLabel, BorderLayout.NORTH);
        frame.add(buttonPanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setSize(500, 500);
        frame.add(solveButton, BorderLayout.SOUTH);

        frame.setVisible(true);
    }

    public static void main(String[] args) {
        MazeGUI maze = new MazeGUI();
        maze.createAndShowGui();
    }
}

这是解算器的界面:

public interface MazeSolver {
    public String[][] solve(String[][] map);
}         

这是我的合作伙伴代码(坐标类):

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;
    }

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

MyMazeSolver类:

import java.util.ArrayList;

public class MyMazeSolver implements MazeSolver {
    private static ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();

    private int row;
    private int col;

    @Override
    public String[][] solve(String[][] map) {
        startingPos(map);
        //for (int i = 0; i < 15; i++) {
        do{
            makeMove(map);

            if (nextToF(map, row, col)) {
                System.out.println(row + "" + col);
                map[row][col] = "X";
            } else {

                if (isExplorable(map, row, col)) {
                    map[row][col] = "D";
                } else {
                    map[row][col] = "X";
                }

                if(deadEnd(map, row, col)){

                }
            }
            addCoordinates(row, col);
            //}
        }while(!isEnded(map));
        print(map);

        // delete printCoordinates
        printCoordinates();
        return map;
    }

    public void startingPos(String[][] map) {
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                if (map[i][j].contains("S")) {
                    row = i;
                    col = j;
                }
            }
        }
    }

    public boolean clear(String[][] map, int row, int col) {


        if (row <= 0 || col <= 0 ||row > map.length) {
            return false;
        }
        if (col <= 0 ||  col > map[0].length) {
            return false;
        }

        if ("S".equals(map[row][col])) {
            return false;
        }
        if ("W".equals(map[row][col])) {
            return false;
        }
        if ("X".equals(map[row][col])) {
            return false;
        }
        if ("D".equals(map[row][col])) {
            return false;
        }

        return true;
    }

    public void makeMove(String[][] map) {
        if (clear(map, row + 1, col)) {
            row++;
        } else if (clear(map, row, col - 1)) {
            col--;
        } else if (clear(map, row, col + 1)) {
            col++;
        } else if (clear(map, row, col)) {
            row--;
        }

    }

    public boolean explorable(String[][] map, int row, int col) {
        if (row > map.length) {
            return false;
        }
        if (col > map[0].length) {
            return false;
        }

        if (map[row][col].equals("S")) {
            return false;
        }
        if (map[row][col].equals("W")) {
            return false;
        }
        if (map[row][col].equals("X")) {
            return false;
        }
        if (map[row][col].equals("D")) {
            return false;
        }

        return true;
    }

    public boolean isExplorable(String[][] map, int row, int col) {
        int squares = 0;

        if (explorable(map, row + 1, col)) {
            squares++;
        }
        if (explorable(map, row, col - 1)) {
            squares++;
        }
        if (explorable(map, row, col + 1)) {
            squares++;
        }
        if (explorable(map, row - 1, col)) {
            squares++;
        }

        if (squares > 1) {
            return true;
        } else {
            return false;
        }
    }

    public void addCoordinates(int row, int col) {
        coordinates.add(new Coordinate(row, col));
    }

    public void printCoordinates() {
        for (int i = 0; i < coordinates.size(); i++) {

            System.out.println(coordinates.get(i));
        }
    }

    public boolean nextToF(String[][] map, int row, int col) {
        if ("F".equals(map[row + 1][col])) {
            // row++;
            map[row + 1][col] = ("RIP");
            return true;
        } else if ("F".equals(map[row][col - 1])) {
            // col--;
            map[row][col - 1] = "RIP";
            return true;
        } else if ("F".equals(map[row][col + 1])) {
            // col++;
            map[row][col + 1] = "RIP";
            return true;
        } else if ("F".equals(map[row - 1][col])) {
            // row--;
            map[row - 1][col] = "RIP";
            return true;
        }
        return false;
    }

    public boolean deadEnd(String[][] map, int row, int col) {
        int deadEnds = 0;

        if (row > map.length) {
            deadEnds++;
        }
        if (col > map[0].length) {
            deadEnds++;
        }
        if (map[row][col].equals("S")) {
            deadEnds++;
        }
        if (map[row][col].equals("W")) {
            deadEnds++;
        }
        if (map[row][col].equals("X")) {
            deadEnds++;
        }
        if (map[row][col].equals("D")) {
            deadEnds++;
        }

        if (deadEnds == 4) {
            return true;
        } else {
            return false;
        }

    }

    public void findD(){

    }

    public boolean isEnded(String[][] map) {
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                if (map[i][j].equals("RIP")) {
                    return true;
                }
            }
        }
        return false;
    }

    public void print(String[][] map) {
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map[0].length; j++) {
                System.out.print(map[i][j]);

            }
            System.out.println();
        }
    }

}

1 个答案:

答案 0 :(得分:2)

  

我在solveButton的ActionListener下调用他的类,但我没有   知道如何在单击JLabel时更新String [] []映射。对于   例如,如果我在(5,5)单击JLabel,地图将更新map [5] [5]   “W”而不是空字符串。

问题在于,您依赖的信息不会改变。

public void mouseClicked(MouseEvent e) {
    if (clicked == false) {
        clicked = true;
        jlabel.setBackground(Color.LIGHT_GRAY);
        map[rowCount - 1][colCount - 1] = "W";

    } else {
        clicked = false;
        jlabel.setBackground(Color.BLACK);
        //map[rowCount - 1][colCount -1 ] = "";

    }
}

在您的代码中,您依赖的是rowCountcolCount,它不会(也可能不会)更改,而只会影响最后一个元素。 JLabel和地图条目之间没有关系。

您需要做的是提供某种链接。在这种情况下,我通常会使用某种Map,键入JLabel并维护我需要的参考来循环map值。

例如......

String[][] map;
// 1
private Map<JLabel, Point> labelMap;
//...
private void createAndShowGui() {
    //...
    map = new String[rowCount][colCount];
    // 2
    labelMap = new HashMap<>(rowCount * colCount);
        //...
        // 3
        labelMap.put(jlabel, new Point(rows - 1, columns - 1));
        jlabel.addMouseListener(new MouseListener() {
  1. 创建类型为Map
  2. 的新实例变量
  3. 使用labelMap
  4. 创建HashMap的新实例
  5. row / column与给定标签
  6. 相关联

    然后在MouseListener中,您需要获取点击的JLabel,获取row数组的关联column / map并制作你的更新......

    jlabel.addMouseListener(new MouseListener() {
        boolean clicked = false;
    
        @Override
        public void mouseClicked(MouseEvent e) {
            // Get the source of the event
            JLabel label = (JLabel)e.getComponent();
            // Get the map indices associated with the given label
            Point point = labelMap.get(label);
    
            // Flip the clicked state
            clicked = !clicked;
            // Update the state accordingly...
            if (clicked) {
                jlabel.setBackground(Color.LIGHT_GRAY);
                map[point.x][point.y] = "W";
            } else {
                jlabel.setBackground(Color.BLACK);
                map[point.x][point.y] = "";
            }
        }
    
      

    此外,当您单击Solve JButton时,它应该突出显示   它所采用的路径,但它只突出显示它的结束位置。如果有的话   解决方案,“F”将变为“RIP”,如果没有解决方案   迷宫,它应该有一个JLabel说迷宫是无法解决的。

    有一些问题导致这种情况无效,你应该看到它们发生时抛出异常。

    我遇到的第一个问题是NullPointerException,这是clear方法在此行if (map[row][col].equals("S"))) {

    引起的

    这立刻告诉我map[row][col]的价值是null。不知道是否应该,不要太在意,因为它很容易使用...

    if ("S".equals(map[row][col]))) {
    

    您需要为此方法中的其他if语句执行此操作。

    我遇到的第二个问题是ArrayIndexOutOfBoundsException,这是makeMove方法造成的

    } else if (clear(map, row, col - 1)) {
    //...
    } else if (clear(map, row - 1, col)) {
    

    这里的主要问题是,当colrow 0时会发生什么?你最终没有对此进行边界检查......

    您可以使用...

    clear方法中解决此问题
    public boolean clear(String[][] map, int row, int col) {
        if (row < 0 || row > map.length) {
            return false;
        }
        if (col < 0 || col > map[0].length) {
            return false;
        }
    

    例如......

    nextToF方法导致了类似问题