等待玩家单击Java中的棋子

等待玩家单击Java中的棋子,java,swing,event-handling,wait,event-dispatch-thread,Java,Swing,Event Handling,Wait,Event Dispatch Thread,实现以下代码的正确方法是什么?我想让takeTurn()方法等待玩家单击网格上与他想要选择的片段对应的按钮。(Button对象具有实例变量int col,row和extend JButton) 运行时在线程“main”java.lang.IllegalMonitorStateException中出现异常我在代码中没有看到任何同步。对象需要处于同步的上下文中,以便等待()工作 int selectedCol, selectedRow; void takeTurn() { System.o

实现以下代码的正确方法是什么?我想让takeTurn()方法等待玩家单击网格上与他想要选择的片段对应的按钮。(
Button
对象具有实例变量
int col,row
extend JButton


运行时在线程“main”java.lang.IllegalMonitorStateException中出现
异常
我在代码中没有看到任何
同步
。对象需要处于
同步的
上下文中,以便
等待()
工作

int selectedCol, selectedRow;

void takeTurn() {
    System.out.print(name + "'s turn. ");

    // Get player to select a piece
    selectedCol = -1;
    selectedRow = -1;
    while (selectedCol == -1 && selectedRow == -1) {
        try {
            wait(500);
        } catch (InterruptedException e) {

        }
    }
    System.out.println(selectedCol + " " + selectedRow);
}

@Override
public void actionPerformed(ActionEvent e) {
    Button b = (Button)e.getSource();
    selectedCol = b.col;
    selectedRow = b.row;
}

创建一个
线程
并在那里运行代码,然后在那里调用
线程。wait()

我在代码中没有看到任何
同步
。对象需要处于
同步的
上下文中,以便
等待()
工作

创建一个
线程
并在那里运行代码,然后在那里调用
线程.wait()

等待()只有在还有notify()时才有意义,所以它总是关于线程之间的通信,需要同步才能正常工作。您的代码似乎缺少基本的等待/通知模型实现

有一个防护块的概念,它说

线程通常必须协调它们的操作。最常见的 协调习语是受保护的块。这样的一个区块始于 轮询一个条件,该条件必须为true才能继续执行块

此处了解更多信息:

wait()仅在同时存在notify()时才有意义,因此它始终与线程之间的通信有关,需要同步才能正常工作。您的代码似乎缺少基本的等待/通知模型实现

有一个防护块的概念,它说

线程通常必须协调它们的操作。最常见的 协调习语是受保护的块。这样的一个区块始于 轮询一个条件,该条件必须为true才能继续执行块

在此了解更多信息:

在Swing或AWT(或大多数UI框架)中,您不应该阻止主事件线程。这将导致您的程序停止,并显示为已崩溃或挂起

相反,您需要根据传入事件监视程序的状态

比如说

  • 接下来,用户转向rest内部变量
  • 用过的一块。保持对工件的引用
  • 使用单击(某些位置)。如果用户选择了一个工件,移动是否有效?等等
在Swing或AWT(或大多数UI框架)中,永远不要阻止主事件线程。这将导致您的程序停止,并显示为已崩溃或挂起

相反,您需要根据传入事件监视程序的状态

比如说

  • 接下来,用户转向rest内部变量
  • 用过的一块。保持对工件的引用
  • 使用单击(某些位置)。如果用户选择了一个工件,移动是否有效?等等

    • 你是说
      线程睡眠(500)
      wait()
      notify()
      /
      notifyAll()
      一起使用,它应该在一个同步的代码块中。谢谢,Thread。睡眠(500)是我一直在寻找的。不要阻止EDT(事件调度线程)-发生这种情况时GUI将“冻结”。不要调用
      Thread.sleep(n)
      为重复任务执行Swing
      计时器,或为长时间运行的任务执行
      SwingWorker
      。有关更多详细信息,请参阅@福阿德我很惊讶你会提出如此有问题的建议。我有理由对你的许多答案投赞成票,但如果这是一个答案,那将是-1(@AndrewThompson为什么你认为
      takeTurn()
      是从EDT调用的?:P..此外,我没有注意到这是一个摇摆问题:)@Eng.Fouad“没有注意到这是一个摇摆问题”,因为只有在你发表评论后才被标记为摇摆问题,你完全可以原谅当我编辑标签以添加(&(基于“swing”)EDT时,
      JButton
      的提示为我做到了这一点你是说
      线程睡眠(500)
      wait()
      notify()
      /
      notifyAll()
      一起使用,它应该在一个同步的代码块中。谢谢,Thread。睡眠(500)是我一直在寻找的。不要阻止EDT(事件调度线程)-发生这种情况时GUI将“冻结”。不要调用
      Thread.sleep(n)
      为重复任务执行Swing
      计时器,或为长时间运行的任务执行
      SwingWorker
      。有关更多详细信息,请参阅@福阿德我很惊讶你会提出如此有问题的建议。我有理由对你的许多答案投赞成票,但如果这是一个答案,那将是-1(@AndrewThompson为什么你认为
      takeTurn()
      是从EDT调用的?:P..此外,我没有注意到这是一个摇摆问题:)@Eng.Fouad“没有注意到这是一个摇摆问题”,因为只有在你发表评论后才被标记为摇摆问题,你完全可以原谅当我编辑标签以添加(&(基于“swing”)EDT时,
      JButton
      的提示为我做到了这一点