在Java的GUI中,当我单击Start按钮时,我希望这个主类WumpusWorld运行某个方法。然后我希望GUI刷新并看到更改。此刻,我点击Start,什么也没发生。编辑-我将给你们我正在使用的所有类。您应该能够在Eclipse中运行它们。我只是想让这个程序在我点击开始时做一些事情,因为目前它什么都不做。
WumpusWorld.java(主类)
import java.util.LinkedList;
public class WumpusWorld {
private static int size;
private static Node startpoint;
private static Node endpoint;
private static int mode;
//private static String[][] nodeTypes;
private static LinkedList<Node> thegrid;
private static WumpusGui wgui;
public static void main(String[] args) {
// Show the GUI
thegrid = new LinkedList<Node>();
wgui = new WumpusGui();
// Set an initial size*/
setSize(5);
}
// Set up the grid
public static void setUpGrid() {
thegrid.clear();
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
thegrid.add(new Node(i, j, "empty"));
}
}
wgui.setGridSize(size);
wgui.setGrid(thegrid);
}
/**
*
*/
public static void run() {
mode = 0; // Manhattan Heuristic
// Ensure that the grid is valid
int start = 0;
int end = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
if(thegrid.get(i*size+j).isGoal()) {
end++;
endpoint = thegrid.get(i*size+j);
} else if(thegrid.get(i*size+j).isRobot()) {
start++;
startpoint = thegrid.get(i*size+j);
}
}
}
if(!(start == 1 && end == 1)) {
return;
}
Pathfinder pathf = new Pathfinder(thegrid);
String temp = pathf.pathfind(startpoint, endpoint, mode);
temp = temp.substring(1);
temp = temp.substring(0, temp.length()-1);
String[] result = temp.split("\)\(");
int finalcounter = result.length;
LinkedList<Node> victoryPath = new LinkedList<Node>();
for (String a : result) {
String[] b = a.split(",");
victoryPath.add(new Node(Integer.parseInt(b[0]), Integer.parseInt(b[1]), "empty"));
System.out.println("lol");
}
for(Node n : victoryPath) {
thegrid.get(n.getX()*size + n.getY()).setType("path");
}
}
// Setter for size
public static void setSize(int newSize) {
size = newSize;
setUpGrid();
}
public static void setStartPos(int x, int y) {
// Remove the old start pos
for(int i=0; i<size*size; i++) {
if(thegrid.get(i).isRobot()) {
thegrid.get(i).setType("empty");
break;
}
}
// Add the new pos
thegrid.get((x*size) + y).setType("robot");
}
public static void setEndPos(int x, int y) {
// Remove the old start pos
for(int i=0; i<size*size; i++) {
if(thegrid.get(i).isGoal()) {
thegrid.get(i).setType("empty");
break;
}
}
// Add the new pos
thegrid.get((x*size) + y).setType("goal");
}
public static void setObstacle(int x, int y) {
// Add the obstacle
thegrid.get((x*size) + y).setType("wall");
}
public static void removeObstacle(int x, int y) {
// Add the obstacle
thegrid.get((x*size) + y).setType("empty");
}
}
WumpusGui.java (JPanel)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import javax.swing.*;
public class WumpusGui extends JFrame {
private static final long serialVersionUID = 1L;
// This GUI
private static WumpusGui wgui;
// Controls
// NxN Grid Input
private JPanel pnlLayoutGrid;
private JLabel lblGrid;
private JTextField txtGrid;
private JButton btnGrid;
// Obstacle input
private JPanel pnlLayoutObstacles;
private JLabel lblObstacleX;
private JTextField txtObstacleX;
private JLabel lblObstacleY;
private JTextField txtObstacleY;
private JButton btnObstacleAdd;
private JLabel lblObstacleLog;
private JPanel pnlLayoutObstacleButtons;
// Start and end box positions
private JPanel pnlStartEndPos;
private JPanel pnlStartPos;
private JLabel lblStartX;
private JTextField txtStartX;
private JLabel lblStartY;
private JTextField txtStartY;
private JButton btnStartPos;
private JPanel pnlEndPos;
private JLabel lblEndPos;
private JLabel lblEndX;
private JTextField txtEndX;
private JLabel lblEndY;
private JTextField txtEndY;
private JButton btnEndPos;
// Start and stop buttons
private JPanel pnlStartStop;
private JButton btnStart;
private JButton btnStop;
// Display
private JPanel pnlDisplay;
private JPanelGrid pnlGraphics;
private JLabel pnlText;
// Window layouts
private JPanel pnlTop;
private JPanel pnlTopLeft;
private JPanel pnlTopRight;
public WumpusGui() {
// Set up window
setTitle("Wumpus World GUI");
setBackground(Color.GRAY);
// Set up controls
Dimension d = new Dimension(50, 25);
// Set up basic layout
pnlTop = new JPanel();
add(pnlTop, BorderLayout.NORTH);
pnlTopLeft = new JPanel();
pnlTopLeft.setLayout(new BoxLayout(pnlTopLeft, BoxLayout.Y_AXIS));
pnlTopRight = new JPanel();
pnlTop.add(pnlTopLeft, BorderLayout.WEST);
pnlTop.add(pnlTopRight, BorderLayout.EAST);
// Set up NxN grid controls
pnlLayoutGrid = new JPanel();
pnlLayoutGrid.setBorder(BorderFactory.createTitledBorder("Grid"));
pnlTopLeft.add(pnlLayoutGrid);
lblGrid = new JLabel("Grid size");
txtGrid = new JTextField();
txtGrid.setPreferredSize(d);
btnGrid = new JButton("Set size");
pnlLayoutGrid.add(lblGrid);
pnlLayoutGrid.add(txtGrid);
pnlLayoutGrid.add(btnGrid);
// Set up start and end position controls
pnlStartEndPos = new JPanel();
pnlStartEndPos.setLayout(new BoxLayout(pnlStartEndPos, BoxLayout.Y_AXIS));
pnlTopLeft.add(pnlStartEndPos);
pnlStartPos = new JPanel();
pnlStartPos.setBorder(BorderFactory.createTitledBorder("Start position"));
pnlStartEndPos.add(pnlStartPos);
lblStartX = new JLabel("X: ");
txtStartX = new JTextField();
txtStartX.setPreferredSize(d);
lblStartY = new JLabel("Y: ");
txtStartY = new JTextField();
txtStartY.setPreferredSize(d);
btnStartPos = new JButton("Set");
pnlStartPos.add(lblStartX);
pnlStartPos.add(txtStartX);
pnlStartPos.add(lblStartY);
pnlStartPos.add(txtStartY);
pnlStartPos.add(btnStartPos);
pnlEndPos = new JPanel();
pnlEndPos.setBorder(BorderFactory.createTitledBorder("End position"));
pnlStartEndPos.add(pnlEndPos);
lblEndX = new JLabel("X: ");
txtEndX = new JTextField();
txtEndX.setPreferredSize(d);
lblEndY = new JLabel("Y: ");
txtEndY = new JTextField();
txtEndY.setPreferredSize(d);
btnEndPos = new JButton("Set");
pnlEndPos.add(lblEndX);
pnlEndPos.add(txtEndX);
pnlEndPos.add(lblEndY);
pnlEndPos.add(txtEndY);
pnlEndPos.add(btnEndPos);
// Set up obstacles controls
pnlLayoutObstacles = new JPanel();
pnlLayoutObstacles.setBorder(BorderFactory.createTitledBorder("Obstacles"));
pnlLayoutObstacles.setLayout(new BoxLayout(pnlLayoutObstacles, BoxLayout.Y_AXIS));
pnlTopRight.add(pnlLayoutObstacles);
lblObstacleX = new JLabel("X: ");
txtObstacleX = new JTextField();
txtObstacleX.setPreferredSize(d);
lblObstacleY = new JLabel("Y: ");
txtObstacleY = new JTextField();
txtObstacleY.setPreferredSize(d);
btnObstacleAdd = new JButton("Add");
pnlLayoutObstacleButtons = new JPanel();
pnlLayoutObstacles.add(pnlLayoutObstacleButtons, BorderLayout.NORTH);
pnlLayoutObstacleButtons.add(lblObstacleX);
pnlLayoutObstacleButtons.add(txtObstacleX);
pnlLayoutObstacleButtons.add(lblObstacleY);
pnlLayoutObstacleButtons.add(txtObstacleY);
pnlLayoutObstacleButtons.add(btnObstacleAdd);
// Graphical display
pnlGraphics = new JPanelGrid();
pnlGraphics.setPreferredSize(new Dimension(200, 200));
pnlGraphics.setN(10);
pnlGraphics.setBackground(Color.WHITE);
add(pnlGraphics, BorderLayout.CENTER);
// Add the start button
btnStart = new JButton("Start");
pnlTopRight.add(btnStart, BorderLayout.SOUTH);
// Button setup
btnGrid.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
WumpusWorld.setSize(Integer.parseInt(txtGrid.getText()));
pnlGraphics.repaint();
} catch(Exception ex) {
// Nothing
}
}
});
btnStartPos.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
WumpusWorld.setStartPos(Integer.parseInt(txtStartX.getText()), Integer.parseInt(txtStartY.getText()));
pnlGraphics.repaint();
} catch(Exception ex) {
// Nothing
}
}
});
btnEndPos.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
WumpusWorld.setEndPos(Integer.parseInt(txtEndX.getText()), Integer.parseInt(txtEndY.getText()));
pnlGraphics.repaint();
} catch(Exception ex) {
// Nothing
}
}
});
btnObstacleAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
WumpusWorld.setObstacle(Integer.parseInt(txtObstacleX.getText()), Integer.parseInt(txtObstacleY.getText()));
pnlGraphics.repaint();
} catch(Exception ex) {
// Nothing
}
}
});
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
WumpusWorld.run();
pnlGraphics.repaint();
} catch(Exception ex) {
// Nothing
}
}
});
pnlGraphics.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
// Get X and Y
int x = e.getX();
int y = e.getY();
// Left click = add obstacle
if(e.getButton() == MouseEvent.BUTTON1) {
pnlGraphics.addObstacle(x, y);
// Right click = remove obstacle
} else {
pnlGraphics.removeObstacle(x, y);
}
pnlGraphics.repaint();
}
// These methods are not used
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
});
// finish off the window
pack();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void drawGrid(int n) {
// Draw the base grid
Graphics g;
}
public static WumpusGui get() {
return wgui;
}
public void setGridSize(int size) {
pnlGraphics.setN(size);
txtGrid.setText(String.valueOf(size));
}
// Set the grid in the graphics display
public void setGrid(LinkedList<Node> thegrid) {
pnlGraphics.setObstacles(thegrid);
}
// Private class used for displaying the grid visually
private class JPanelGrid extends JPanel {
private int n; // width/height of grid
private LinkedList<Node> obstacles;
private LinkedList<Clickable> clickables = new LinkedList<>();
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
// Set up dimensions
int width = getWidth();
int height = getHeight();
int gridX = 10;
int gridY = 10;
int gridW = width-20;
int gridH = height-20;
// Draw the grid's background
g.setColor(Color.BLACK);
g.fillRect(gridX, gridY, gridW, gridH);
// Empty the clickable list
clickables.clear();
// Draw cells
int nodePointer = 0;
if(obstacles != null) {
for(int i=0, ii=0; ii<n; i+=(gridW/n), ii++) {
for(int j=0, jj=0; jj<n; j+=(gridH/n), jj++) {
// Set the color depending on the node's type
if(obstacles.get(nodePointer).isEmpty()) {
g.setColor(Color.WHITE);
} else if(obstacles.get(nodePointer).isWall()) {
g.setColor(Color.DARK_GRAY);
} else if(obstacles.get(nodePointer).isRobot()) {
g.setColor(Color.RED);
} else if(obstacles.get(nodePointer).isEmpty()) {
g.setColor(Color.CYAN);
} else {
g.setColor(Color.YELLOW);
}
// Draw the rectangle
int x = gridX + (int)i + 1;
int y = gridY + (int)j + 1;
int w = gridW/n - 2;
int h = gridH/n - 2;
clickables.add(new Clickable(x, y, w, h, ii, jj));
g.fillRect(x, y, w, h);
// Draw the X and Y coords
g.setColor(Color.GRAY);
g.drawString("x" + ii + ", y" + jj, x+4, y+11);
nodePointer++;
}
}
}
}
// Setter for N (size)
public void setN(int n) {
this.n = n;
}
// Setter for obstacles
public void setObstacles(LinkedList<Node> obstacles) {
this.obstacles = obstacles;
}
public void addObstacle(int x, int y) {
for(Clickable c : clickables) {
if(c.inside(x, y)) {
WumpusWorld.setObstacle(c.getX(), c.getY());
}
}
}
public void removeObstacle(int x, int y) {
for(Clickable c : clickables) {
if(c.inside(x, y)) {
WumpusWorld.removeObstacle(c.getX(), c.getY());
}
}
}
// This class is used to allow the user to click on the grid to add an obstacle.
private class Clickable {
private Rectangle rect;
private int x;
private int y;
public Clickable(int rectX, int rectY, int width, int height, int x, int y) {
rect = new Rectangle(rectX, rectY, width, height);
this.x = x;
this.y = y;
}
public boolean inside(int x, int y) {
return rect.contains(x, y);
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
}
}
Pathfinder.java (A*搜索算法)
import java.util.HashSet;
import java.util.HashMap;
import java.util.Iterator;
import java.lang.Math;
public class Pathfinder {
/**
* Variable for the cost of each movement on the grid. Only for up/down/left/right movement.
* Use {@link #setMovementCost(double)} to change from an external class.
*/
private double movementCost = 1.0;
/**
* Storage variable for the input
*/
private Iterable<Node> iterableInput; //Input
/**
* Storage variable for the G-cost of the node, in A*
* <p>
* F = G + H
*/
private HashMap<Node,Double> gmap; //map of travel cost
/**
* Storage variable for the F-cost of the node, in A*
* <p>
* F = G + H
*/
private HashMap<Node,Double> fmap; //map of predicted total cost
/**
* Storage variable for a map of the paths on the grid. Every evaluated node points to its predecessor.
*/
private HashMap<Node,Node> navmap; //map of path to each node
/**
* Variable for which Pathfinding Heuristic to use.
* <p>
* Used in {@link #heuristicCost(Node, Node, int)}
* <p>
* default = Manhattan Distance
* <p>
* 1 = Diagonal Distance
*/
private static int heuristicMode;
/**
* General Pathfinder constructor
* <p>
* Takes iterable input as a parameter - use anything that extends Iterable
*
* @param input iterable input of nodes/boxes, such as a list
*/
public Pathfinder(Iterable<Node> input) {
iterableInput=input;
}
/**
* Pathfind the correct path
* <p>
* There is only one public method and it returns a path in the form of a String.
* <p>
* Parsing the answer string is not included in this class.
*
* @param start the starting node
* @param goal the finishing node
* @param mode integer for the heuristic being used
* @return String path of the form (0,0)(0,1)...
*/
public String pathfind(Node start, Node goal, int mode) {
heuristicMode=mode;
return astar(start, goal);
}
/**
* A* method.
* <p>
* Algorithm adapted from Wikipedia.
*
* @param start the starting node
* @param goal the finishing node
* @return String path of the form (0,0)(0,1)...
*/
private String astar(Node start, Node goal) {
HashSet<Node> closedset = new HashSet<Node>(); //set of evaluated nodes
HashSet<Node> openset = new HashSet<Node>(); //set of nodes to be evaluated
openset.add(start); //first node to be evaluated
gmap=populateHashMap(iterableInput); //initialize HashMap of visited Nodes
navmap=new HashMap<Node,Node>();
fmap=populateHashMap(iterableInput);
//Heuristic: F=G+H
//F = total cost
//G = path cost
//H = heuristic cost
//put appropriate G for start
gmap.put(start, 0.0);
fmap.put(start, gmap.get(start) + ManhattanDistance(start, goal)); //heuristic cost of 0
Node current;
while(!openset.isEmpty()) {
current = getCheapest(openset);
if(sameNode(current, goal))
return constructPath(navmap,goal);
openset.remove(current);
closedset.add(current);
HashSet<Node> neighbors = getNeighbors(current, heuristicMode);
for(Node neighbor : neighbors) {
if(closedset.contains(neighbor))
continue;
double temp_g = gmap.get(current) + movementCost;
if(!openset.contains(neighbor) || temp_g<gmap.get(neighbor)) {
navmap.put(neighbor, current);
gmap.put(neighbor,temp_g);
fmap.put(neighbor, gmap.get(neighbor) + heuristicCost(neighbor, goal, heuristicMode));
if(!openset.contains(neighbor))
openset.add(neighbor);
}
}
}
return "failed";
}
/**
* Set the cost for each movement.
* <p>
* This is for the up/down/left/right directions. The cost for moving diagonally is calculated based on that.
* @param cost the cost of moving up/down/left/right
*/
public void setMovementCost(double cost) {
movementCost=cost;
}
//Cost Heuristic
/**
* Heuristic switch function.
*
* @param current the current node
* @param goal the goal node
* @param mode the switch integer. Default for Manhattan. 1 for Diagonal.
* @return the cost that the switched-to heuristic has calculated
*/
private double heuristicCost(Node current, Node goal, int mode) {
switch(mode){
case 1: return DiagonalDistance(current, goal);
default: return ManhattanDistance(current,goal);
}
}
//Manhattan Distance
/**
* Manhattan Distance heuristic.
* <p>
* Adapted from http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
*
* @param current the current node
* @param goal the goal node
* @return the H-cost of the current node
*/
private double ManhattanDistance(Node current, Node goal) {
return movementCost*(Math.abs(current.getX()-goal.getX())+Math.abs(current.getY()-goal.getY()));
}
//Diagonal Distance
/**
* Diagonal Distance heuristic.
* <p>
* Adapted from http://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html
*
* @param current the current node
* @param goal the goal node
* @return the H-cost of the current node
*/
private double DiagonalDistance(Node current, Node goal) {
return movementCost*(Math.abs(current.getX()-goal.getX())+Math.abs(current.getY()-goal.getY())) + (Math.sqrt(2)*movementCost-2*movementCost)*Math.min(Math.abs(current.getX()-goal.getX()), Math.abs(current.getY()-goal.getY()));
}
//Populating the Navigation Map
//All Values set to -1.0
/**
* Populates HashMap with parameter iterable input
* @param input the input which gets fed into the hashmap
*/
private HashMap<Node,Double> populateHashMap(Iterable<Node> input) {
HashMap<Node,Double> hashmap = new HashMap<Node,Double>();
Iterator<Node> iterator=input.iterator();
while(iterator.hasNext()) {
hashmap.put(iterator.next(), -1.0);
}
return hashmap;
}
//Getting the Cheapest Node from a HashSet
/**
* Gets the cheapest node of the openset
* @param openset the set of open nodes
* @return the node with the cheapest F-cost
*/
private Node getCheapest(HashSet<Node> openset) {
Iterator<Node> iterator=openset.iterator();
Node thisNode = iterator.next();
Node nextNode;
while(iterator.hasNext()) {
nextNode=iterator.next();
if(fmap.get(nextNode)<fmap.get(thisNode))
thisNode=nextNode;
}
return thisNode;
}
//Get the Neighbors of a Node
/**
* Gets the neighbors of the parameter node, based on the Heuristic mode
*
* @param current the current node
* @param mode the Heuristic mode. See {@link #heuristicMode}
* @return a HashSet of the neighboring nodes
*/
private HashSet<Node> getNeighbors(Node current, int mode) {
HashSet<Node> result = new HashSet<Node>();
HashSet<Node> keySet=(HashSet<Node>) gmap.keySet();
Iterator<Node> iterator=keySet.iterator();
while(iterator.hasNext()) {
Node thisNode=iterator.next();
//Manhattan movement
if(thisNode.getX()+1 == current.getX() && thisNode.getY() == current.getY())
result.add(thisNode);
else if(thisNode.getX()-1 == current.getX() && thisNode.getY() == current.getY())
result.add(thisNode);
else if(thisNode.getX() == current.getX() && thisNode.getY()+1 == current.getY())
result.add(thisNode);
else if(thisNode.getX() == current.getX() && thisNode.getY()-1 == current.getY())
result.add(thisNode);
//Diagonal movement
else if(mode==1) {
if(thisNode.getX()+1 == current.getX() && thisNode.getY()+1 == current.getY())
result.add(thisNode);
else if(thisNode.getX()+1 == current.getX() && thisNode.getY()-1 == current.getY())
result.add(thisNode);
else if(thisNode.getX()-1 == current.getX() && thisNode.getY()+1 == current.getY())
result.add(thisNode);
else if(thisNode.getX()-1 == current.getX() && thisNode.getY()-1 == current.getY())
result.add(thisNode);
}
}
return result;
}
//Same Nodes
//Checks whether the nodes are the same, based on their x and y
/**
* Checks for node similarity. This is included here in order to reduce class inter-dependency
* <p>
* Compares the results from getX() and getY() for each node.
* @param thisNode the first compared node
* @param otherNode the second compared node
* @return TRUE if their coordinates are the same
*/
private boolean sameNode(Node thisNode, Node otherNode) {
return thisNode.getX()==otherNode.getX() && thisNode.getY()==otherNode.getY();
}
//Path Constructor
//Returns String of Nodes in the form of (0,0)(0,1)...
/**
* Constructs a path from the parameter node and the now valued {@link #navmap}
* <p>
* Returns String with tokens built in {@link #toNodeString(Node)}
*
* @param hashmap the navmap
* @param last the goal -or- last node
* @return the String of nodes leading to the parameter node
*/
private String constructPath(HashMap<Node,Node> hashmap, Node last) {
String t;
if(hashmap.containsKey(last)) {
t = constructPath(hashmap, hashmap.get(last));
return (t + last);
}
else {
return toNodeString(last);
}
}
//Nodes to Strings in the form of "(x,y)"
/**
* Turns a node into a String
*
* @param a the parameter node
* @return the node represented in the String form of "(x,y)"
*/
private String toNodeString(Node a) {
return "("+a.getX()+","+a.getY()+")";
}
}
Node.java (Node类)
public class Node {
private int x;
private int y;
private boolean isEmpty, isWall, isRobot, isGoal;
/**
* Basic constructor.
* <p>
* Takes coordinates x, y, and box type.
*
* @param x the X coordinate
* @param y the Y coordinate
* @param type String for the type: "empty", "wall", "robot", "goal"
*/
public Node(int x, int y, String type) {
this.x = x;
this.y = y;
isEmpty=false;
isWall=false;
isRobot=false;
isGoal=false;
if(type.equalsIgnoreCase("empty"))
isEmpty=true;
else if(type.equalsIgnoreCase("wall"))
isWall=true;
else if(type.equalsIgnoreCase("robot"))
isRobot=true;
else if(type.equalsIgnoreCase("goal"))
isGoal=true;
}
/**
* Gets the x coordinate.
*
* @return the X coordinate
*/
public int getX() {
return x;
}
/**
* Gets the y coordinate.
*
* @return the Y coordinate
*/
public int getY() {
return y;
}
/**
* Checks if empty.
*
* @return true if empty
*/
public boolean isEmpty() {
return isEmpty;
}
/**
* Checks if is wall.
*
* @return true if wall
*/
public boolean isWall() {
return isWall;
}
/**
* Checks if is robot.
*
* @return true if robot
*/
public boolean isRobot() {
return isRobot;
}
/**
* Checks if is goal.
* @return true if goal
*/
public boolean isGoal() {
return isGoal;
}
/**
* Sets the type of the box
* <p>
* Does nothing with invalid input
*
* @param type String representing the type: "empty", "wall", "robot", "goal"
*/
public void setType(String type) {
if(type.equalsIgnoreCase("empty")) {
isWall=false;
isEmpty=true;
isRobot=false;
isGoal=false;
}
else if(type.equalsIgnoreCase("wall")) {
isWall=true;
isEmpty=false;
isRobot=false;
isGoal=false;
}
else if(type.equalsIgnoreCase("robot")) {
isWall=false;
isEmpty=false;
isRobot=true;
isGoal=false;
}
else if(type.equalsIgnoreCase("goal")) {
isWall=false;
isEmpty=false;
isRobot=false;
isGoal=true;
}
}
}
Java使用专用线程来管理GUI和相关事件,该线程称为事件分派线程。你不能在ActionListener
回调中直接执行密集任务,因为这将在Swing线程上执行,并使GUI无响应。
你应该使用不同的线程来管理这个,有许多可能的解决方案,像使用一个普通的线程调用repaint()
或SwingWorker
。点击这里和这里查看更多信息