问题描述
|
我正在编写一个Reversi应用程序。我实现了转弯管理器类,但在while循环中遇到了一些小问题。
这是我的片段:
while (!table.isFull() || passFlag != 2) {
if (player1.isActive()) {
for (int i = 0; i < table.getSize(); i++) {
for (int j = 0; j < table.getSize(); j++) {
table.getField(i,j).addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Field) {
((Field) e.getSource()).changeToBlack();
}
}
});
}
}
}
if (player2.isActive()) {
for (int i = 0; i < table.getSize(); i++) {
for (int j = 0; j < table.getSize(); j++) {
table.getField(i,j).addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Field) {
((Field) e.getSource()).changeToWhite();
}
}
});
}
}
}
sentinel.changeActivePlayer(player1,player2);
该表是按钮的网格,而字段是按钮。循环不等待玩家互动。如何实现代码,使其等待用户的鼠标单击?
这是此类的完整代码
package Core;
import GUILayer.Field;
import GUILayer.MainFrame;
import elements.Player;
import elements.Table;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TurnManager {
int passFlag = 0;
int TurnFlag = 0;
Sentinel sentinel = new Sentinel();
public TurnManager() {
}
public void manage(MainFrame mainframe,Table table,Player player1,Player player2) {
while (!table.isFull() || passFlag != 2) {
if (player1.isActive()) {
for (int i = 0; i < table.getSize(); i++) {
for (int j = 0; j < table.getSize(); j++) {
table.getField(i,j).addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Field) {
((Field) e.getSource()).changeToBlack();
}
}
});
}
}
}
if (player2.isActive()) {
for (int i = 0; i < table.getSize(); i++) {
for (int j = 0; j < table.getSize(); j++) {
table.getField(i,j).addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Field) {
((Field) e.getSource()).changeToWhite();
}
}
});
}
}
}
sentinel.changeActivePlayer(player1,player2);
}
}
}
解决方法
这不是一个完整的解决方案,但是您的代码应该看起来像这样。我认为这是将事物融合在一起的好起点。希望这可以帮助。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TurnManager implements ActionListener{
int passFlag = 0;
int TurnFlag = 0;
Sentinel sentinel = new Sentinel();
Player player1,player2;
public TurnManager(MainFrame mainframe,Table table,Player p1,Player p2) {
player1 = p1;
player2 = p2;
for (int i = 0; i < table.getSize(); i++) {
for (int j = 0; j < table.getSize(); j++) {
table.getField(i,j).addActionListener(this);
}
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Field) {
Field field = ((Field) e.getSource());
//implement logic here,for example:
if (table.isFull())
throw new RuntimeException(\"Table full! Stop! STOP!\");
if (player1.isActive())
field.changeToBlack();
if (player2.isActive())
field.changeToBlack();
}
}
}
, 我同意Howards的评论...这看起来设计很错误。使用侦听器和事件意味着您(大部分时间)不必自己使用事件循环。
请尝试以下操作:创建一个容纳您的电路板的类。董事会知道每个字段具有什么颜色(以及它需要知道的其他所有内容)。初始化GUI时,您将创建单个EventListener,该EventListener调用板对象的某些方法。该方法通过了被单击的字段(我想它被单击了,还是我错了吗?)。您将对此EventListener的引用存储在变量中。然后,您遍历每个for和column并将此侦听器附加到每个字段。然后显示GUI。
让我澄清一下:所有这些都是在初始化时完成的。
, 一些建议:
如前所述,不需要while循环,拥有它们(即使它们确实起作用了)也可以使代码成为非事件驱动的。
您要从视图中分离模型。该模型-应该完全忽略视图-将知道轮到谁了。它将具有一个非静态字段,该字段将告诉它轮到谁了,枚举对此非常有效,并且当需要更改术语时,此字段的值也会更改。
每个单元都将附加一个侦听器(或“控件”),可能是同一侦听器(根据Martin的帖子-为他+1),并且侦听器的唯一工作就是告诉模型单击哪个单元格,可以通过在侦听器的Event参数上调用getSource获得信息。如果侦听器是ActionListener,则我要谈论的事件将是传递到侦听器的actionPerformed方法中的ActionEvent对象。
然后,模型将基于按下哪个单元格和轮到谁来决定如何处理信息(如果有)。
视图(GUI)将侦听模型更改(可能使用PropertyChangeListener或您自己创建的另一个侦听器),并将根据模型的状态更改其显示。