在Java Swing中使用ChangeListener触发更改?

在Java Swing中使用ChangeListener触发更改?,java,swing,actionlistener,changelistener,Java,Swing,Actionlistener,Changelistener,我正在实现一个猜字游戏。附上的图片给出了我正在做的事情的想法。我的GamePane由两个组件组成,ControlPane和HangManPane,这是所附图像的顶部和底部。当玩家单击,newgame按钮时,必须通知GamePane。随后,GamePane将从ControlPane请求SecretWord,并将其传递给HangManPane,以构建模型 所以这里发生了两件事,我想知道如何实现 ControlPane应该在用户单击“New Game”(新游戏)按钮时触发通知。因此,此fireChan

我正在实现一个猜字游戏。附上的图片给出了我正在做的事情的想法。我的
GamePane
由两个组件组成,
ControlPane
HangManPane
,这是所附图像的顶部和底部。当玩家单击,
newgame
按钮时,必须通知
GamePane
。随后,
GamePane
将从
ControlPane
请求SecretWord,并将其传递给
HangManPane
,以构建模型

所以这里发生了两件事,我想知道如何实现

  • ControlPane应该在用户单击“New Game”(新游戏)按钮时触发通知。因此,此fireChange应该发生在
    New Game
    按钮的ActionListener中

  • GamePane
    侦听通知并将信息传递给
    HangManPane

  • 使用
    ChangeListener
    是合适的。我做了我的搜索部分,但无法掌握如何在这里实现。欢迎提出任何建议

    public class GamePane extends JPanel {
    
        public GamePane(){
             ControlPane cp = new ControlPane();
             //if user clicks New Game on ControlPane, notify me
             //I will then do the following 
             HangManModel model = new DefaultHangManModel(cp.getSecretWord());
             HangManPane hangManPane = new HangManPane(model);
    
             setLayout(new GridLayout(0,1));
             this.add(cp);
             this.add(pane);
    
        }
     }
    

    提供侦听器支持“相对”简单。由于
    JComponent
    将它的
    EventListenerList
    listenerList
    )作为
    受保护的
    变量公开,因此它被简化了

    控制窗格中
    ,您需要一个add方法

    public void addChangeListener(ChangeListener listener) {
        listenerList.add(ChangeListener.class, listener);
    }
    
    您需要一个remove方法

    public void removeChangeListener(ChangeListener listener) {
        listenerList.remove(ChangeListener.class, listener);
    }
    
    现在,您需要一些方法来根据需要实际引发或激发事件

    protected void fireStateChanged() {
        ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
        if (listeners != null && listeners.length > 0) {
            ChangeEvent evt = new ChangeEvent(evt);
            for (ChangeListener listener : listeners) {
                listener.stateChanged(evt);
            }
        }
    }
    
    现在,当您想要告诉注册的侦听器
    ControlPane
    状态已更改时,您只需调用
    fireStateChanged
    ,例如

    public void actionPerformed(ActionEvent evt) {
        fireStateChanged();
    }
    
    现在,在
    GamePane
    中,您需要针对
    ControlPane
    的实例注册一个
    ChangeListener

    private ControlPane cp;
    private HangManPane hangManPane;
    
    //...
    
    public GamePane() {
        cp = new ControlPane();
        hangManPane = new HangManPane(null);
    
        cp.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent evt) {
                String secret = cp.getSecretWord();
                DefaultHangManModel model = new DefaultHangManModel(secret);
                hangManPane.setModel(model);
            }
        });
    }
    

    例如…

    另请参见本文中的
    Model#reset()
    。此处的listenerlist是什么?以及为什么
    ChangeListener[]listeners=listenerList.getListeners(ChangeListener.class)是否需要?我想只有一个我感兴趣的
    监听器
    ,没有一个正确的列表吗?现在有没有办法在游戏结束后(赢或输)从HangManPane触发对ControlPane的更改1-
    listenerList
    如我所说,是在
    JComponent
    中声明的,它是
    EventListenerList
    的一个实例,这是一种维护一组不同侦听器列表的简洁方法,因此2-
    listenerList.getListeners(ChangeListener.class)
    返回以前使用
    addChangeListener
    注册过的所有
    ChangeListener
    ,您永远不知道谁将来可能想要侦听;)。。。3-我可能会做的是,当
    GamePanel
    创建一个新模型时,向它注册一个
    HangManListener
    ,这样当游戏丢失或赢了时,就会通知你,然后我会提供一种方法,你可以“启用”/“禁用”
    ControlPane
    …我得到一个编译错误'changevent evt=new changevent(evt);<代码>,这是因为未声明
    evt`变量。如果您不介意,您能逐行告诉fireStateChanged方法的作用吗?非常感谢你
    public void actionPerformed(ActionEvent evt) {
        fireStateChanged();
    }