簡體   English   中英

在Java中實現觀察者模式,跨多個類使用同一觀察者

[英]Implementing the observer pattern in Java, same observer across multiple classes

因此,我正在修改一個現有的開源項目,創建了一個新的監視器類,該類用於使用觀察者模式觀察現有類中的更改,該類本身正在由其他一些監視類進行監視。

在原始系統的主類中,我可以使用它,但是,當程序切換到其他類時,我試圖通過新類的構造函數(由包含發送的接口Manager表示)傳遞管理器。 ()函數,程序將使用該函數更新監視器。但是,當我嘗試從另一個類調用send時,它不起作用(它在名為Main的第一類中起作用)。

當我在此新類中聲明的“ MouseHandler”類中調用send()時,出現以下錯誤:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at kabalpackage.GameArea$MouseHandler.mouseReleased(GameArea.java:565)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

我嘗試在此MouseHandler類中聲明另一個Manager變量,並將其傳遞給構造函數,但遇到了相同的錯誤。

這是它工作的類,為簡單起見,我省略了很多代碼。

/*added necessary imports */
import java.util.*;
import monitors.Manager;
import monitors.MonManager;


 public class Main
 extends JFrame
 {
//  added manager variable
public static Manager manager;

public Main(Manager m)
{
     // this is where I set the manager provided in the constructor
             this.manager = m;

    // ..... lots of code skipped

    //  I try and pass the manager in to the new class here
private GameArea gameArea = new GameArea(manager);

private class MenuBar
extends JMenuBar
{
    //.....lots of code skipped
    }

    private class MenuListener
    implements ActionListener
    {
        private MenuListener() {}

        public void actionPerformed(ActionEvent e)
        {
            String event = e.getActionCommand();
            if (event.equals("New Game"))
            {


                // here is where i call send on the monitor
                                    System.out.println("Sending win 0"); 
                manager.send("win 0");
                Main.this.gameArea.newGame();
                System.out.println("New game");

                    }
                }
            }
        }
    }
}

如您所見,在該類中聲明了一個新類。 這是從上面的類調用的GameArea類,您可以看到我修改了構造函數以采用一個管理器(接口)對象,因此可以將SAME監視器管理器傳遞給下一個類。 我再次從此類中省略了很多代碼,包括一些導入(它仍然具有import java.util。*;我認為這是發送事件所必需的)。

import monitors.MonManager;
import monitors.Manager;

public class GameArea
extends JPanel
{
public static Manager manager;
    // loads of variables omitted //

// heres the constructor for the class, a manager is passed in and set to variable Manager
    public GameArea(Manager m)
{
    setLayout(null);
    setBackground(this.BACKGROUND_COLOR);
    setCursor(new Cursor(12));
    this.manager = m;

    loadImages();
}
    // more code omitted //
public void newGame()
{
    removeAll();
            // this creates the mouse handler class where i try to call manager.send
    MouseHandler mh = new MouseHandler();


}


    // more code omitted //

public class MouseHandler
extends MouseInputAdapter
{   
    // variables omitted

    private MouseHandler() {
    }

    public void mouseMoved(MouseEvent e)
    {
         //
    }

    public void mousePressed(MouseEvent e)
    {
        // omitted code //
    }    
    public void mouseDragged(MouseEvent e)
    {
        // omitted code //
    }

    public void mouseClicked(MouseEvent e)
    {
        // omitted code
    }

    public void mouseReleased(MouseEvent e)
    {
        // more omitted code
            if ((this.SRC_STACK instanceof DealtCardsStack)) {
                GameArea.this.moves.clear();
                // a call of manager
                System.out.println("Sending moves");
                manager.send("moves");
            } else {
                GameArea.this.moves.add(new Move(this.SRC_STACK, this.DST_STACK, this.TMP_LIST));
                // Here is the call for the manager, which creates an error.
                System.out.println("Sending moves");
                manager.send("moves");
            }
        }
        else
        {
            this.SRC_STACK.showCards(this.TMP_LIST);
        }
    // skipped some code//
}

}

最后,這是我的管理員界面中由監視器管理器實現的代碼:

package monitors;

public interface Manager {

    public void send(String message);
} 

如果問題不清楚,我們很抱歉。 有很多代碼可以省略,因此看起來很凌亂,但是我認為遺漏的任何內容都不會對錯誤產生影響。 因此,基本上在Main類中,我的消息被發送到實現Manager的監視器,但是在另一類中,它們不是,並且我也不知道為什么。

非常感謝有耐心閱讀的任何人,如果您能說出我的問題所在,也特別感謝!

字段初始化是在實際構造函數執行之前完成的,因此該行

private GameArea gameArea = new GameArea(manager);

正在傳遞未初始化的管理器,從而導致NullPointerException。

只需將初始化放入構造函數中即可: gameArea = new GameArea(manager); 解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM