简体   繁体   English

我需要在Java的JPanel上实现A *算法的帮助

[英]I need help implementing A* algorithm on a JPanel in Java

I'm learning java and for the last couple of days i haven't been able to make any progress.I have searched all over Google and this site,but i can't seem to find exactly the solution i need.A similar problem or something. 我正在学习Java,最近几天我一直没有取得任何进展。我在Google和这个网站上进行了搜索,但是我似乎找不到确切的解决方案。类似的问题或者其他的东西。 I'm trying to implement the A* algorithm on a simple JPanel which has a grid layout,with no success.Currently i have a run time error,the program compiles just fine.I know the solution might be something really simple,so please bear with me if i haven't figured that out.Sometimes we just need an extra set of eyes to see what we can't.Thank you so much for your your time and your help. 我正在尝试在具有网格布局的简单JPanel上实现A *算法,但没有成功。当前我遇到了运行时错误,程序可以正常编译。我知道解决方案可能非常简单,所以请如果我还没有弄清楚,请多多包涵。有时我们只需要多看一些眼神,看看我们做不到。非常感谢您的时间和帮助。

Anyway,here's what I've tried so far,there are only two classes and the Grid class has the UI features and a start button which is meant to instantiate the Maze class that runs the A* algorithm: 无论如何,到目前为止,这是我已经尝试过的方法,只有两个类,并且Grid类具有UI功能和一个开始按钮,用于实例化运行A *算法的Maze类:

My Grid class,which has the main method 我的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();
            }
        });
    }
}

The other class called Maze which has the algorithm: 另一个称为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;
    }
}

And this is the error i get: 这是我得到的错误:

 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)

Basically, you have public JPanel [][] panelcontainer; 基本上,您具有public JPanel [][] panelcontainer; , which is fine, but then you fill it with JPanel s ,这很好,但是您可以使用JPanel填充它

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

And then you try and cast it to a Grid ... 然后您尝试将其投射到Grid ...

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

But panelcontainer doesn't contain Grid s, it contains JPanel s. 但是panelcontainer不包含Grid ,它包含JPanel

It would be like filling a bus with African Elephants and expecting them to magically change to Indian Elephants when they arrive at their destination...Yes, they are Elephants, but they are not the same TYPE of Elephant... 这就像在给非洲大象加满一辆巴士,并期望它们在到达目的地时神奇地变成印度大象...是的,它们是大象,但它们不是同一类大象...

I suspect that if you changed the createSquares method to generate instances of Grid instead of JPanel , you should be able to move forward a little more... 我怀疑如果您更改了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();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM