2011-05-29 63 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或其他偵聽器創建自己的偵聽器,並將根據模型的狀態更改其顯示。