我正在学习 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)