2011-05-29 45 views
0

我在写一个Reversi应用程序。我实现了轮流管理器类,但是我在while循环中遇到了一些问题。等待while循环中的用户操作 - JAVA

这是我的代码片段:

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); 
     } 
    } 
} 
+0

如果这是功课,请标记为这样。此外,该代码可以受益于一些重构... – 2011-05-29 09:27:02

+4

你能否提供一个更完整的例子。你的while循环在哪里?在我看来,这是一个破碎的设计。 while循环将听众一遍又一遍地分配给你的按钮。 – Howard 2011-05-29 09:27:38

回答

0

这不是一个完整的解决方案,但你的代码应该看起来更像这样。我认为这是一起开始合作的好起点。希望这可以帮助。

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(); 
     } 
    } 
} 
4

我与霍华德的评论表示赞同......这看起来很misdesigned的全部代码。使用监听器和事件意味着你(大部分时间)不必自己使用事件循环。

请尝试以下操作:创建一个持有您的主板的类。董事会知道每个领域有什么颜色(以及其他需要知道的)。当您的GUI初始化时,您创建了单个 EventListener调用板对象的某种方法。这个方法通过被点击的字段(我想它被点击了,还是我错了?)。您将一个对此EventListener的引用存储在一个变量中。然后循环遍历每一列和列,并将此侦听器附加到每个字段。然后你显示GUI。

让我澄清一下:所有这些都是在初始化时完成的。

+0

感谢帮助。主要问题是Listeners konwledge失踪,但我学到了......解决方案是,我创建了一个自己的监听器类,它由ActionListener实现,并在actionPerformed方法中实现了事件驱动的操作......所以再次感谢这些想法和帮助。 BR。 – 2011-06-02 07:46:23

0

几点建议:

  • 如前所述,没有必要为您的while循环,并让他们(即使他们没有工作),使你的代码的非事件驱动的。
  • 您想将模型与视图分开。这个模型 - 应该对视图相当无知 - 会知道是谁转向它。它将会有一个非静态字段来告诉它轮到谁了,一个枚举可以很好地工作,当需要改变条件时,这个字段的值会改变。
  • 每个单元格都会附加一个监听器(或“控制”),可能是同一个监听器(根据Martin的post - +1),而监听器的唯一工作是告诉模型哪个单元被点击,通过调用监听器的Event参数上的getSource可获得的信息。如果侦听器是一个ActionListener,那么我所说的事件将是传入侦听器的actionPerformed方法的ActionEvent对象。
  • 模型将决定如何处理这些信息,如果有的话,基于哪个单元格被按下以及哪个单元正在转动。
  • 视图(GUI)将侦听模型更改,可能使用PropertyChangeListener或其他侦听器创建自己的侦听器,并将根据模型的状态更改其显示。