重绘方法没有及时发挥作用

时间:2015-05-08 12:51:39

标签: java

我用Java制作游戏,而repaint()方法却以一种非常奇怪的方式行为不端。基本上,我需要在进行人工智能移动之前重新绘制电路板。这是我的方法,我称之为:

public void mouseClicked(MouseEvent e) {
    mouseX = e.getX();
    mouseY = e.getY();

    int button = e.getButton();
    if (button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3) {
        int mouseR = (mouseY / SIZE);
        int mouseC = (mouseX / SIZE);

        if (mouseR >= 0 && mouseC >= 0 &&
                mouseR < board.length && mouseC < board[0].length) {
            if (board[mouseR][mouseC] == 3) {
                makeMove(mouseR, mouseC, playerColor);
                getValidMoves((playerColor % 2) + 1);
                repaint();
                getAIMove();
            }
        }

    }
    repaint();
}

getAIMove()的设计是为了让它在移动前等待几秒钟,因此玩家可以在看到AI之前看到移动的结果。不幸的是,虽然我在repaint()之前拨打getAIMove(),但更多的情况是:玩家点击他们想要移动的位置。几秒钟内似乎没有任何事情发生,然后玩家移动的结果和AI的移动显示在屏幕上。发生了什么事?

2 个答案:

答案 0 :(得分:2)

option事件处理程序中的所有代码都将在特殊的AWT / Swing Thread上运行。

mouseClicked()不会立即重新绘制GUI - 它计划重新绘制,(请参阅this article),它也将在Swing线程上运行 - 但直到您的事件处理程序已经完成 - Swing线程一次只能做一件事!

所以直到事后你才会看到repaint()的结果。

您可能需要在单独的后台线程中运行getAIMove()逻辑,然后更新GUI(必须使用SwingUtilities.invokeLater()getAIMove()帮助程序类在Swing线程中完成。)

或者,您可以使用SwingWorker安排AI在Swing线程上运行 - 然后它将在第一个invokeLater()之后运行。但是,这种方法是不可取的(除非AI非常快),因为在Swing线程再次释放以处理重新绘制之前,GUI将无响应。

另请参阅有关这些主题的Java教程:

答案 1 :(得分:0)

一位朋友和我想出了一个小技巧来击败@DNA描述的队列 - 这是我的新代码:

public void mousePressed( MouseEvent e )
   {
      mouseX = e.getX();
      mouseY = e.getY();

      int button = e.getButton();
      if(button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3)
      {
         int mouseR = (mouseY/SIZE);
         int mouseC = (mouseX/SIZE);

         if(mouseR >=0 && mouseC >= 0 && mouseR < board.length && mouseC < board[0].length)
         {
            if (board[mouseR][mouseC] == 3){
               makeMove(mouseR, mouseC, playerColor);
            }
         }

      } 
      repaint();
   }

   public void mouseReleased( MouseEvent e )
   {
      int button = e.getButton();
      if(button == MouseEvent.BUTTON1 || button == MouseEvent.BUTTON3)
      {
         int mouseR = (mouseY/SIZE);
         int mouseC = (mouseX/SIZE);

         if(mouseR >=0 && mouseC >= 0 && mouseR < board.length && mouseC < board[0].length)
         {
            if (board[mouseR][mouseC] == playerColor){
               getValidMoves((playerColor % 2) + 1);
               getAIMove();
               getValidMoves(playerColor);
            }
         }

      } 
      repaint();
   }

通过在按下鼠标时进行玩家移动,并等待AI移动直到释放鼠标,程序可以完成Swing线程并重新绘制板。感谢您的所有帮助!