Java Swing - ScheduledExecutorService 停止处理用户输入
Java Swing - ScheduledExecutor Service Stops working upon UserInput
我正在建造一个迷宫,怪物会在其中跟踪玩家并向其移动。我有一个名为 SwapCells 的函数,我认为问题出在这里。SwapCells 用于移动 Monster 和 Player。我有一个运行 Monstermover 的 ScheduledExecutorService,它使用 SwapCells。游戏开始时怪物开始移动,现在问题是当我开始移动玩家时,ScheduledExecutorService 停止工作,我只能移动玩家。我认为问题在于,与 MoveMonster 不同,Keylistener 不是 ScheduledExecutorService 的一部分,因此当我调用 KeyListener 反过来运行 SwapCell 时,它会使 ScheduledExecutorService 停止。有什么建议吗?请帮忙!
private final int CELLSIZE = 20;
private ArrayList<Level> levels = new ArrayList<Level>();
private Player player;
private Monster monster;
private DisplayInfo display;
private int xSize;
private int ySize;
private int currentLevel = 0;
private int direction = 0;
//private CountDownTimer timer = new CountDownTimer(15);
public Game(int xSize, int ySize) {
player = new Player(0,0);
monster = new Monster(0,1);
setXSize(xSize);
setYSize(ySize);
setLayout(new GridLayout(ySize, xSize));
addLevel();
addKeyListener(new KeyListener() {
// POSSIBLE PROBLEM IS HERE !!
@Override
public void keyPressed(KeyEvent event) {
if(!hitWall) }
swapCells(getCurrentLevel().getMap()[x+dx][y+dy], getCurrentLevel().getMap()[x][y], player);
}
}
}
});
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(() -> moveMonster(), 0L, 1000L, TimeUnit.MILLISECONDS);
}
public void swapCells(Cell cell1, Cell cell2, Mover mover) {
Icon tempIcon = cell1.getLabel().getIcon();
String tempID = cell1.getID();
// sets mover's x and y value
mover.setX(cell1.getX());
mover.setY(cell1.getY());
// sets mover's cell to new cell
getCurrentLevel().getpMaze().setCell(cell1, mover);
getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].setID(cell2.getID());
getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].getLabel().setIcon(cell2.getLabel().getIcon());
getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].setID(tempID);
getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].getLabel().setIcon(tempIcon);
}
public void moveMonster() {
PerfectMaze currentMaze = getCurrentLevel().getpMaze();
ArrayList<Cell> trackToPlayer = currentMaze.getTrack(currentMaze.getMonsterCell(), currentMaze.getPlayerCell(), "P");
Collections.reverse(trackToPlayer);
Cell nextCell = trackToPlayer.get(1);
//swapCells(nextCell, currentMaze.getMonsterCell(), monster);
swapCells(getCurrentLevel().getMap()[nextCell.getX()][nextCell.getY()], getCurrentLevel().getMap()[monster.getX()][monster.getY()], monster);
}
您应该只与来自 Swing "Event Dispatch Thread" (EDT) 的 Swing 组件进行交互。但是你创建了一个ExecutorService
,它的线程直接在操作Swing组件。
相反,在 SwingWorker
, 中执行后台工作,它可以将图形更新安全地传递给 EDT。
我正在建造一个迷宫,怪物会在其中跟踪玩家并向其移动。我有一个名为 SwapCells 的函数,我认为问题出在这里。SwapCells 用于移动 Monster 和 Player。我有一个运行 Monstermover 的 ScheduledExecutorService,它使用 SwapCells。游戏开始时怪物开始移动,现在问题是当我开始移动玩家时,ScheduledExecutorService 停止工作,我只能移动玩家。我认为问题在于,与 MoveMonster 不同,Keylistener 不是 ScheduledExecutorService 的一部分,因此当我调用 KeyListener 反过来运行 SwapCell 时,它会使 ScheduledExecutorService 停止。有什么建议吗?请帮忙!
private final int CELLSIZE = 20;
private ArrayList<Level> levels = new ArrayList<Level>();
private Player player;
private Monster monster;
private DisplayInfo display;
private int xSize;
private int ySize;
private int currentLevel = 0;
private int direction = 0;
//private CountDownTimer timer = new CountDownTimer(15);
public Game(int xSize, int ySize) {
player = new Player(0,0);
monster = new Monster(0,1);
setXSize(xSize);
setYSize(ySize);
setLayout(new GridLayout(ySize, xSize));
addLevel();
addKeyListener(new KeyListener() {
// POSSIBLE PROBLEM IS HERE !!
@Override
public void keyPressed(KeyEvent event) {
if(!hitWall) }
swapCells(getCurrentLevel().getMap()[x+dx][y+dy], getCurrentLevel().getMap()[x][y], player);
}
}
}
});
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
executor.scheduleAtFixedRate(() -> moveMonster(), 0L, 1000L, TimeUnit.MILLISECONDS);
}
public void swapCells(Cell cell1, Cell cell2, Mover mover) {
Icon tempIcon = cell1.getLabel().getIcon();
String tempID = cell1.getID();
// sets mover's x and y value
mover.setX(cell1.getX());
mover.setY(cell1.getY());
// sets mover's cell to new cell
getCurrentLevel().getpMaze().setCell(cell1, mover);
getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].setID(cell2.getID());
getCurrentLevel().getMap()[cell1.getX()][cell1.getY()].getLabel().setIcon(cell2.getLabel().getIcon());
getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].setID(tempID);
getCurrentLevel().getMap()[cell2.getX()][cell2.getY()].getLabel().setIcon(tempIcon);
}
public void moveMonster() {
PerfectMaze currentMaze = getCurrentLevel().getpMaze();
ArrayList<Cell> trackToPlayer = currentMaze.getTrack(currentMaze.getMonsterCell(), currentMaze.getPlayerCell(), "P");
Collections.reverse(trackToPlayer);
Cell nextCell = trackToPlayer.get(1);
//swapCells(nextCell, currentMaze.getMonsterCell(), monster);
swapCells(getCurrentLevel().getMap()[nextCell.getX()][nextCell.getY()], getCurrentLevel().getMap()[monster.getX()][monster.getY()], monster);
}
您应该只与来自 Swing "Event Dispatch Thread" (EDT) 的 Swing 组件进行交互。但是你创建了一个ExecutorService
,它的线程直接在操作Swing组件。
相反,在 SwingWorker
, 中执行后台工作,它可以将图形更新安全地传递给 EDT。