2011-02-27 77 views
1

所以我有我的主要類在這裏,基本上創建一個新的jframe並添加一個世界對象。世界對象基本上是所有繪畫和關鍵字發生的地方......Java KeyListener在單獨的類

public class Blobs extends JFrame{ 

    public Blobs() { 
     super("Blobs :) - By Chris Tanaka"); 
     setVisible(true); 
     setResizable(false); 
     setSize(1000, 1000); 
     setIgnoreRepaint(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     add(new World()); 
    } 

    public static void main(String[] args) { 
     new Blobs(); 
    } 
} 

您將如何從世界級獲得關鍵輸入? (到目前爲止,我有我的世界級延伸的JPanel並實施的KeyListener在構造函數中我addKeyListener(本)我也有這些方法,因爲它們是自動實現的:。

public void keyPressed(KeyEvent e) { 
    if (e.getKeyCode() == KeyEvent.VK_W) 
     System.out.println("Hi"); 
} 

public void keyReleased(KeyEvent e) {} 
public void keyTyped(KeyEvent e) {} 

然而,這似乎並沒有工作?

+0

我們可以看到世界一流的通知方法? – 2011-02-27 05:05:42

回答

3

如果您想通知「觀察班級」您的世界班級出現KeyPress事件,那麼這是利用觀察員的好時機。結構想是這樣的:

public interface Observer 
{ 
    public void update(KeyEvent keyEvent); 
} 

public interface Observable 
{ 
    public void NotifyObservers(KeyEvent keyEvent); 
} 

public class World implements KeyListener, Observable 
{ 
    private ArrayList<Observer> obsList; 

    public World() 
    { 
     obsList = new ArrayList(); 
    } 

    public void keyPressed(KeyEvent e) 
    { 
     NotifyObservers(e); 
    } 

    public void keyReleased(KeyEvent e) {} 
    public void keyTyped(KeyEvent e) {} 

    public void NotifyObservers(KeyEvent keyEvent) 
    { 
     for(Observer obs : obsList) 
     { 
      obs.update(keyEvent); 
     } 
    } 

    public void AddObserver(Observer obs) 
    { 
     if (obs != null) 
      obsList.add(obs); 
    } 

    public void DelObserver(Observer obs) 
    { 
     if (obs != null) 
      obsList.remove(obs); 
    } 
} 

public class Blobs extends JFrame implements Observer 
{ 

    public Blobs() 
    { 
     super("Blobs :) - By Chris Tanaka"); 

     //Register this instance of Blobs as an observer that is stored in the World's 
     //obsList ArrayList field 
     World world = new World(); 
     world.addObserver(this); 

     setResizable(false); 
     setSize(1000, 1000); 
     setIgnoreRepaint(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     getContentPane().add(world); 
     this.addKeyListener(world); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new Blobs(); 
    } 

    public void update(KeyEvent keyEvent) 
    { 
     //do whatever here when key event occurs 
    } 
} 

所以這裏最終的結果是,你可以實現我所定義的obsList觀察員接口部分的任何類。然後,當發生keyevent時,它將調用NotifyObservers()方法遍歷列表並調用Observing類中的update()方法。

編輯:

你可以同時擁有世界和戰鬥類處理以自己的方式的關鍵事件,如果你需要的話。

public class Battle implements Observer 
{ 

    public void update(KeyEvent e) 
    { 
     // do processing here 
    } 
} 

public class Blobs implements Observer 
{ 
    public void update(KeyEvent e) 
    { 
     // do processing here 
    } 
} 

你只需要在某些時候加入戰鬥作爲觀察員參加你的世界級的就像我在斑點

worldInstance.addObserver(new Battle()); 

另外做了,如果你想使用的標誌,只允許某些類處理的KeyEvents那麼你可以簡單地更新接口,允許合格標誌的更新方法爲這樣:

public interface Observer 
{ 
    public void update(object isFor, KeyEvent e); 
} 

那麼觀察者更新的方法將有這種流:

public class Battle 
{ 
    public void update(object flag, KeyEvent e) 
    { 
     if (flag instanceof Battle) 
     { 
      //now do your work 
     } 
    } 
} 

這也意味着更新可觀察接口和實現者

+0

@Chris如果您對這件作品有何疑問,請告訴我。一旦你理解了一些更精細的點,這一切都是有道理的,並使事件驅動的邏輯傳遞給其他類進行處理更容易。 – 2011-02-27 05:40:45

+0

我一直在看這個代碼,它似乎我的理解是,你的解決方案,我將不得不將我的主要Blob類中的按鍵處理的所有代碼? 也只是爲了更具體我想要的是讓我的世界類處理我的角色(油漆和按鍵處理)的所有世界運動和處理單獨的鍵控和繪圖的戰鬥類。換句話說,我希望能夠在我的世界級中進行戰鬥=新戰鬥(),一旦戰鬥結束,控制將恢復到世界。 – Bob 2011-03-07 10:22:17

+0

@Chris關於在Blob類中處理所有密鑰處理的假定不正確。他們的觀察者之美就是你可以有不止一個。看看上面的編輯。 – 2011-03-07 16:03:32

1

如果您Worls類實現KeyListener的,然後做你正在嘗試做的是改變斑點構造這樣一種方式,

public Blobs() { 
     super("Blobs :) - By Chris Tanaka"); 
     setVisible(true); 
     setResizable(false); 
     setSize(1000, 1000); 
     setIgnoreRepaint(true); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     World world = new World(); 
     getContentPane().add(world); 
     this.addKeyListener(world); 
     setVisible(true); 
} 
+0

並確保「世界」是可以關注的。 (不知道它是否默認) – 2011-02-27 05:17:21

1

它不會因爲默認情況下JPanels不要工作沒關注焦點,可能是s通過將其可調焦屬性設置爲true並請求焦點來達到。

但話雖如此,我認爲你的JPanel類不實現一個監聽器接口是很重要的,因爲你最好使用匿名內部類來監聽器。你甚至可以使用鍵綁定而不是關鍵的監聽器,但是我不能根據迄今爲止提供的數據來判斷。