0

我正在学习 Java,在过去的几天里我一直没有取得任何进展。我在谷歌和这个网站上搜索过,但我似乎找不到我需要的确切解决方案。类似的问题或者其他的东西。我正在尝试在具有网格布局的简单 JPanel 上实现 A* 算法,但没有成功。目前我有一个运行时错误,程序编译得很好。我知道解决方案可能非常简单,所以请如果我还没有弄清楚,请耐心等待。有时我们只需要一双额外的眼睛来看看我们看不到的东西。非常感谢您的时间和帮助。

无论如何,这是我迄今为止尝试过的,只有两个类,Grid 类具有 UI 功能和一个开始按钮,用于实例化运行 A* 算法的 Maze 类:

我的 Grid 类,它有 main 方法

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Grid extends JPanel {

    private boolean start;
    private boolean end;
    public int x;
    public int y;
    public JPanel parent;
    private double localCost; // cost of getting from this square to goal i.e 'H'
    private double parentCost; // cost of getting from parent square to this node i.e 'G'
    private double passThroughCost;// cost of getting from the start to the goal i.e 'F'
// through this square
    private static final long serialVersionUID = 1L;
    private Set<JPanel> adjacencies = new HashSet<JPanel>();
    public JPanel mainPanel, southPanel;
    public final JFrame mainFrame = new JFrame();
    public static int a = 7;
    public static int b = 7;
    public JPanel[][] panelcontainer = new JPanel[a][b];
    private Maze maze;

    public Grid() {
        mainPanel = new JPanel();
        mainPanel.setLayout(new GridLayout(a, b));
        for (int i = 0; i < a; i++) {
            for (int j = 0; j < b; j++) {
                panelcontainer[i][j] = new JPanel();
                panelcontainer[i][j].setBorder(BorderFactory.createLineBorder(Color.black, 1));
                panelcontainer[i][j].setBackground(Color.blue);
                mainPanel.add(panelcontainer[i][j]);
                mainPanel.setBackground(Color.darkGray);
            }
        }
        //setting colors on the cells within the grid
        panelcontainer[3][1].setBackground(Color.GREEN);
        panelcontainer[2][3].setBackground(Color.darkGray);
        panelcontainer[3][3].setBackground(Color.darkGray);
        panelcontainer[4][3].setBackground(Color.darkGray);
        panelcontainer[1][5].setBackground(Color.darkGray);
        panelcontainer[2][5].setBackground(Color.darkGray);
        panelcontainer[0][0].setBackground(Color.darkGray);
        //  panelcontainer[0][0].setStart(true);
        panelcontainer[0][1].setBackground(Color.darkGray);
        panelcontainer[1][1].setBackground(Color.darkGray);
        panelcontainer[1][6].setBackground(Color.ORANGE);
        //populating each cell with the total movement costs
        JLabel label1 = new JLabel("84");
        label1.setForeground(Color.black);
        panelcontainer[0][2].add(label1);
        JLabel label2 = new JLabel("78");
        label2.setForeground(Color.black);
        panelcontainer[0][3].add(label2);
        JLabel label3 = new JLabel("78");
        label3.setForeground(Color.black);
        panelcontainer[0][4].add(label3);
        JLabel label4 = new JLabel("78");
        label4.setForeground(Color.black);
        panelcontainer[0][5].add(label4);
        JLabel label5 = new JLabel("78");
        label5.setForeground(Color.black);
        panelcontainer[0][6].add(label5);
        JLabel label6 = new JLabel("84");
        label6.setForeground(Color.black);
        panelcontainer[1][0].add(label6);
        JLabel label7 = new JLabel("64");
        label7.setForeground(Color.black);
        panelcontainer[1][2].add(label7);
        JLabel label8 = new JLabel("64");
        label8.setForeground(Color.black);
        panelcontainer[1][3].add(label8);
        JLabel label9 = new JLabel("64");
        label9.setForeground(Color.black);
        panelcontainer[1][4].add(label9);
        JLabel label10 = new JLabel("84");
        label10.setForeground(Color.black);
        panelcontainer[2][0].add(label10);
        JLabel label11 = new JLabel("70");
        label11.setForeground(Color.black);
        panelcontainer[2][1].add(label11);
        JLabel label12 = new JLabel("64");
        label12.setForeground(Color.black);
        panelcontainer[2][2].add(label12);
        JLabel label13 = new JLabel("84");
        label13.setForeground(Color.black);
        panelcontainer[2][4].add(label13);
        JLabel label14 = new JLabel("104");
        label14.setForeground(Color.black);
        panelcontainer[2][6].add(label14);
        JLabel label15 = new JLabel("90");
        label15.setForeground(Color.black);
        panelcontainer[3][0].add(label15);
        JLabel label16 = new JLabel("70");
        label16.setForeground(Color.black);
        panelcontainer[3][2].add(label16);
        JLabel label17 = new JLabel("104");
        label17.setForeground(Color.black);
        panelcontainer[3][4].add(label17);
        JLabel label18 = new JLabel("104");
        label18.setForeground(Color.black);
        panelcontainer[3][5].add(label18);
        JLabel label19 = new JLabel("104");
        label19.setForeground(Color.black);
        panelcontainer[3][6].add(label19);
        JLabel label20 = new JLabel("104");
        label20.setForeground(Color.black);
        panelcontainer[4][0].add(label20);
        JLabel label21 = new JLabel("90");
        label21.setForeground(Color.black);
        panelcontainer[4][1].add(label21);
        JLabel label22 = new JLabel("84");
        label22.setForeground(Color.black);
        panelcontainer[4][2].add(label22);
        JLabel label23 = new JLabel("124");
        label23.setForeground(Color.black);
        panelcontainer[4][4].add(label23);
        JLabel label24 = new JLabel("118");
        label24.setForeground(Color.black);
        panelcontainer[4][5].add(label24);
        JLabel label25 = new JLabel("118");
        label25.setForeground(Color.black);
        panelcontainer[4][6].add(label25);
        JLabel label26 = new JLabel("104");
        label26.setForeground(Color.black);
        panelcontainer[5][0].add(label26);
        JLabel label27 = new JLabel("110");
        label27.setForeground(Color.black);
        panelcontainer[5][1].add(label27);
        JLabel label28 = new JLabel("104");
        label28.setForeground(Color.black);
        panelcontainer[5][2].add(label28);
        JLabel label29 = new JLabel("98");
        label29.setForeground(Color.black);
        panelcontainer[5][3].add(label29);
        JLabel label30 = new JLabel("98");
        label30.setForeground(Color.black);
        panelcontainer[5][4].add(label30);
        JLabel label31 = new JLabel("98");
        label31.setForeground(Color.black);
        panelcontainer[5][5].add(label31);
        JLabel label32 = new JLabel("98");
        label32.setForeground(Color.black);
        panelcontainer[5][6].add(label32);
        JLabel label33 = new JLabel("144");
        label33.setForeground(Color.black);
        panelcontainer[6][0].add(label33);
        JLabel label34 = new JLabel("138");
        label34.setForeground(Color.black);
        panelcontainer[6][1].add(label34);
        JLabel label35 = new JLabel("124");
        label35.setForeground(Color.black);
        panelcontainer[6][2].add(label35);
        JLabel label36 = new JLabel("118");
        label36.setForeground(Color.black);
        panelcontainer[6][3].add(label36);
        JLabel label37 = new JLabel("112");
        label37.setForeground(Color.black);
        panelcontainer[6][4].add(label37);
        JLabel label38 = new JLabel("112");
        label38.setForeground(Color.black);
        panelcontainer[6][5].add(label38);
        JLabel label39 = new JLabel("112");
        label39.setForeground(Color.black);
        panelcontainer[6][6].add(label39);
        //new panel at the south border to hold start button
        southPanel = new JPanel();
        // --- Create a button. Add a listener to it.
        JButton startButton = new JButton("start");
        southPanel.add(startButton);
        southPanel.setBackground(Color.red);
        startButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Maze maze = new Maze(7, 7);
                maze.findBestPath();

            }
        });
        //JFrame specifications
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.add(mainPanel, BorderLayout.CENTER);
        mainFrame.add(southPanel, BorderLayout.PAGE_END);
        mainFrame.pack();
        mainFrame.setVisible(true);
        mainFrame.setSize(464, 485);
        mainFrame.setTitle("Astar Simulation");
        mainFrame.setLocationRelativeTo(null);
    }

    public boolean isStart() {
        return start;
    }

    public void setStart(boolean start) {
        this.start = start;
    }

    public boolean isEnd() {
        return end;
    }

    public void setEnd(boolean end) {
        this.end = end;
    }

    public Set<JPanel> getAdjacencies() {
        return adjacencies;
    }

    public void setAdjacencies(Set<JPanel> adjacencies) {
        this.adjacencies = adjacencies;
    }

    public JPanel getParent() {
        return parent;
    }

    public void setParent(JPanel parent) {
        this.parent = parent;
    }

    public void calculateAdjacencies() {
        int top = x - 1;
        int bottom = x + 1;
        int left = y - 1;
        int right = y + 1;
        if (bottom < maze.getRows()) {
            if (isAdjacent()) {
                ((Grid) maze.getPanel(bottom, y)).addAdjacency(this);
                this.addAdjacency(maze.getPanel(bottom, y));
            }
        }
        if (right < maze.getColumns()) {
            if (isAdjacent()) {
                ((Grid) maze.getPanel(x, right)).addAdjacency(this);
                this.addAdjacency(maze.getPanel(x, right));
            }
        }
    }

    public void addAdjacency(JPanel panel) {
        adjacencies.add(panel);
    }

    public void removeAdjacency(JPanel panel) {
        adjacencies.remove(panel);
    }

    private boolean isAdjacent() {
        if (Math.random() > 5) {
            return true;
        }
        return false;
    }

    public double getPassThrough(JPanel goal) {
        if (isStart()) {
            return 0.0;
        }
        return getLocalCost(goal) + getParentCost();
    }

    public double getLocalCost(JPanel goal) {
        if (isStart()) {
            return 0.0;
        }
        localCost = 10.0 * (Math.abs(x - goal.getX()) + Math.abs(y - goal.getY()));
        return localCost;
    }

    public double getParentCost() {
        if (isStart()) {
            return 0.0;
        }
        if (parentCost == 0.0) {
            parentCost = 10.0 + 5 * (((Grid) parent).getParentCost() - 10.0);
        }
        return parentCost;
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Grid();
            }
        });
    }
}

另一个名为 Maze 的类具有以下算法:

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Set;
import javax.swing.JPanel;

public class Maze extends Grid {

    public int rows;
    public int columns;
    public JPanel goal;
    public Grid grid;
    public JPanel[][] panelcontainer;
    private List<JPanel> opened = new ArrayList<JPanel>();
    private List<JPanel> closed = new ArrayList<JPanel>();
    private List<JPanel> bestList = new ArrayList<JPanel>();

    public Maze(int rows, int columns) {
        new Grid();
        this.rows = rows;
        this.columns = columns;
        panelcontainer = new JPanel[rows][columns];
        generate();
    }

    private void generate() {
        createSquares();
        setStartAndGoal();
        generateAdjacenies();
    }

    public int getRows() {
        return rows;
    }

    public int getColumns() {
        return columns;
    }

    private void createSquares() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                panelcontainer[i][j] = new JPanel();
            }
        }
    }

    private void setStartAndGoal() {
        ((Grid) panelcontainer[1][1]).setStart(true);
        Random random = new Random();
        int goalX = 0, goalY = 0;
        while (goalX == 0 && goalY == 0) {
            goalX = random.nextInt(rows);
            goalY = random.nextInt(columns);
        }
        goal = panelcontainer[goalX][goalY];
        ((Grid) goal).setEnd(true);
    }

    private void generateAdjacenies() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                ((Grid) panelcontainer[i][j]).calculateAdjacencies();
            }
        }
    }

    public JPanel getPanel(int x, int y) {
        return panelcontainer[x][y];
    }

    public void setPanel(JPanel panel) {
        panelcontainer[panel.getX()][panel.getY()] = panel;
    }

    public void drawPath() {
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < columns; j++) {
                JPanel panel = panelcontainer[i][j];
                if ((j - 1 < 0) && (i - 1 < 0)) {
                    if (bestList.contains(panel)) {
                        panelcontainer[i][j].setBackground(Color.CYAN);
                        return;
                    }
                }
            }
        }
    }

    public void findBestPath() {
        System.out.println("Calculating best path...");
        Set<JPanel> adjacencies = ((Grid) panelcontainer[0][0]).getAdjacencies();
        for (JPanel adjacency : adjacencies) {
            ((Grid) adjacency).setParent(panelcontainer[0][0]);
            if (((Grid) adjacency).isStart() == false) {
                opened.add(adjacency);
            }
        }
        while (opened.size() > 0) {
            JPanel best = findBestPassThrough();
            opened.remove(best);
            closed.add(best);
            if (((Grid) best).isEnd()) {
                //System.out.println("Found Goal");
                populateBestList(goal);
                drawPath();
                return;
            } else {
                Set<JPanel> neighbors = ((Grid) best).getAdjacencies();
                for (JPanel neighbor : neighbors) {
                    if (opened.contains(neighbor)) {
                        neighbor = panelcontainer[getX()][getY()];
                        JPanel tmpPanel = new JPanel();
                        tmpPanel = neighbor;
                        ((Grid) tmpPanel).setParent(best);
                        if (((Grid) tmpPanel).getPassThrough(goal) >= ((Grid) neighbor)
                                .getPassThrough(goal)) {
                            continue;
                        }
                    }
                    if (closed.contains(neighbor)) {
                        neighbor = panelcontainer[getX()][getY()];
                        JPanel tmpPanel = new JPanel();
                        tmpPanel = neighbor;
                        /*  JPanel tmpPanel = new JPanel(neighbor.getX(),
                         neighbor.getY(), this);*/
                        ((Grid) tmpPanel).setParent(best);
                        if (((Grid) tmpPanel).getPassThrough(goal) >= ((Grid) neighbor)
                                .getPassThrough(goal)) {
                            continue;
                        }
                    }
                    ((Grid) neighbor).setParent(best);
                    opened.remove(neighbor);
                    closed.remove(neighbor);
                    opened.add(0, neighbor);
                }
            }
        }//  System.out.println("No Path to goal");
    }

    private void populateBestList(JPanel panel) {
        bestList.add(panel);
        if (((Grid) panel.getParent()).isStart() == false) {
            populateBestList((JPanel) panel.getParent());
        }
        return;
    }

    private JPanel findBestPassThrough() {
        JPanel best = null;
        for (JPanel panel : opened) {
            if (best == null
                    || ((Grid) panel).getPassThrough(goal) < ((Grid) best).getPassThrough(goal)) {
                best = panel;
            }
        }
        return best;
    }
}

这是我得到的错误:

 Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: javax.swing.JPanel cannot be cast to Grid
at Maze.setStartAndGoal(Maze.java:58)
at Maze.generate(Maze.java:32)
at Maze.<init>(Maze.java:27)
at Grid$1.actionPerformed(Grid.java:238)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2341)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6505)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6270)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4861)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4492)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4687)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:735)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:694)
at java.awt.EventQueue$3.run(EventQueue.java:692)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:708)
at java.awt.EventQueue$4.run(EventQueue.java:706)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:705)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
4

1 回答 1

3

基本上,你有public JPanel [][] panelcontainer;,这很好,但是你用JPanels填充它

private void createSquares() {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            panelcontainer[i][j] = new JPanel();
        }
    }
}

然后您尝试将其转换为Grid...

((Grid) panelcontainer [1][1]).setStart(true);

panelcontainer不包含Grids,它包含JPanels。

这就像用非洲大象装满一辆公共汽车,并期望它们在到达目的地时神奇地变成印度大象......是的,它们是大象,但它们不是同一类型的大象......

我怀疑如果您更改createSquares生成实例的方法,Grid而不是JPanel,您应该能够再前进一点......

private void createSquares() {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < columns; j++) {
            panelcontainer[i][j] = new Grid();
        }
    }
}
于 2013-09-23T05:57:22.503 回答