在do-while循环中更新定时器上的JButton

我有一些麻烦得到一个JButton重复更新(使用一个计时器)在一个do-while循环。 我正在做一个简单的游戏,在一个10 * 10的瓦片对象的网格上玩,这个网格对应着一个有100个button的JButton arrayList。

这部分程序处理简单的寻路(即如果我点击字符,然后是一个空的瓷砖,angular色将通过每个瓷砖到达目的地)。 每个步骤之间有一个延迟,用户可以看到angular色的进度。

在目前的情况下,运动是正确的,但JButton只是在字符到达目的地时才更新,而不是中间步骤。

public void move(int terrainTile) { int currentPosition = actorList.get(selectedActor).getPosition(); int movementValue = 0; int destination = terrainTile; int destinationX = destination / 10; int destinationY = destination % 10; do { currentPosition = actorList.get(selectedActor).getPosition(); // Gets PC's current position (before move) System.out.println("Old position is " + currentPosition); int currentX = currentPosition / 10; int currentY = currentPosition % 10; if(actorList.get(selectedActor).getCurrentAP() > 0) { movementValue = 0; if(destinationX > currentX) { movementValue += 10; } if(destinationX < currentX) { movementValue -= 10; } if(destinationY > currentY) { movementValue += 1; } if(destinationY < currentY) { movementValue -= 1; } int nextStep = currentPosition + movementValue; myGame.setActorIdInTile(currentPosition, -1); //Changes ActorId in PC current tile back to -1 scrubTiles(currentPosition); actorList.get(selectedActor).setPosition(nextStep); // Sets new position in actor object System.out.println("Actor " + selectedActor + " " + actorList.get(selectedActor).getName() + " position has been updated to " + nextStep); myGame.setActorIdInTile(nextStep, selectedActor); // Sets ActorId in moved to Tile System.out.println("Tile " + nextStep + " actorId has been updated to " + selectedActor); buttons.get(nextStep).setIcon(new ImageIcon(actorList.get(selectedActor).getImageName())); // If orthagonal move AP-4 if(movementValue == 10 || movementValue == -10 || movementValue == 1 || movementValue == -1) { actorList.get(selectedActor).reduceAP(4); } // If diagonal move AP-6 else { actorList.get(selectedActor).reduceAP(6); } System.out.println(actorList.get(selectedActor).getName() + " has " + actorList.get(selectedActor).getCurrentAP() + " AP remaining"); try { Thread.sleep(500); // one second } catch (Exception e){} buttons.get(nextStep).repaint(); } else { System.out.println(actorList.get(selectedActor).getName() + " has insufficient AP to move"); break; } }while(destination != (currentPosition + movementValue)); 

我试过了:

  1. buttons.get(NEXTSTEP).repaint(); (尝试设置imageIcon后重新命令button,没有改变。

  2. buttons.get(NEXTSTEP).revalidate(); (没有100%确定这是什么 – 它是一个潜在的解决scheme,但不起作用。

  3. 步骤1和2合并

  4. 看着摇摆定时器类 – 运动不会发生每次一个actionEvent被触发,(只有当字符被选中,目标瓷砖是空的)所以不知道如何才能得到这个工作

任何帮助将不胜感激!

我真的不知道你的意见到底是什么,虽然上面的答案+1,在我看来,这是真正的原因。 看看这个例子程序,只需将你的调用添加到timerAction里面的move(...)方法,看起来好像可以为你工作。 这里试试这个代码:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class GridExample { private static final int SIZE = 36; private JButton[] buttons; private int presentPos; private int desiredPos; private Timer timer; private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon"); private ActionListener timerAction = new ActionListener() { public void actionPerformed(ActionEvent ae) { buttons[presentPos].setIcon(null); if (desiredPos < presentPos) { presentPos--; buttons[presentPos].setIcon(infoIcon); } else if (desiredPos > presentPos) { presentPos++; buttons[presentPos].setIcon(infoIcon); } else if (desiredPos == presentPos) { timer.stop(); buttons[presentPos].setIcon(infoIcon); } } }; public GridExample() { buttons = new JButton[SIZE]; presentPos = 0; desiredPos = 0; } private void createAndDisplayGUI() { JFrame frame = new JFrame("Grid Game"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel contentPane = new JPanel(); contentPane.setLayout(new GridLayout(6, 6, 5, 5)); for (int i = 0; i < SIZE; i++) { final int counter = i; buttons[i] = new JButton(); buttons[i].setActionCommand("" + i); buttons[i].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { desiredPos = Integer.parseInt( (String) buttons[counter].getActionCommand()); timer.start(); } }); contentPane.add(buttons[i]); } buttons[presentPos].setIcon(infoIcon); frame.setContentPane(contentPane); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); timer = new Timer(1000, timerAction); } public static void main(String... args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new GridExample().createAndDisplayGUI(); } }); } } 

这是因为您在UI线程中正在执行do {}。 为了解决这个问题,你应该使用一个SwingWorker或一个javax.swing.Timer