3

I am implementing a word guessing game. The attached image gives an idea of what I am doing. My GamePane consists of two components, ControlPane and HangManPane, which is the top and bottom section of the attached image. when the player clicks, New Game button, the GamePane must be notified. subsequently, the GamePane will request the SecretWord from ControlPane and pass it on to HangManPane to construct the model.

so two things happen here which I would like to know how to implement

  1. ControlPane should fire notifications when the user clicks "New Game" button.so this fireChange should happen in the ActionListener of the New Game button.

  2. GamePane listens to the notifications and pass the information to HangManPane

Using ChangeListener would be appropriate. I did my part of searching, but unable to grasp on how to implement here. Any suggestions are kindly welcome

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);

    }
 }

enter image description here

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
brain storm
  • 30,124
  • 69
  • 225
  • 393

1 Answers1

4

Providing listener support is "relatively" simple. It's simplified by the fact the JComponent exposes it's EventListenerList (listenerList) as a protected variable.

In the ControlPane, you'll need an add method...

public void addChangeListener(ChangeListener listener) {
    listenerList.add(ChangeListener.class, listener);
}

You'll need a remove method

public void removeChangeListener(ChangeListener listener) {
    listenerList.remove(ChangeListener.class, listener);
}

Now, you need some way to actually raise or fire events as needed...

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

Now, when ever you want to tell registered listeners that the ControlPane state has changed, you would simply call fireStateChanged, for example...

public void actionPerformed(ActionEvent evt) {
    fireStateChanged();
}

Now, in the GamePane, you will need to register a ChangeListener against the instance of the ControlPane...

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

For example...

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • what is the listenerlist here? and why `ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);` is needed? I guess there is only one `Listener` I am interested, not a list of them correct? – brain storm Nov 23 '13 at 09:11
  • now is there way a to fire change to ControlPane from HangManPane once the game is over (either won or lost) – brain storm Nov 23 '13 at 09:12
  • 1
    1- `listenerList` is, as I said, declared in `JComponent` which is an instance of `EventListenerList`, which is a neat way to maintain a list of a bunch of different listeners, hence 2- `listenerList.getListeners(ChangeListener.class)` returns all the `ChangeListener`s which have being previously registered with the use of `addChangeListener` and you never know who might want to listen in the future ;)... – MadProgrammer Nov 23 '13 at 09:47
  • 1
    3- What I might do, is when ever `GamePanel` creates a new model, register a `HangManListener` to it, so that when ever the game is lost or won, you would be notified, then I would provide a means by which you could "enable"/"disable" the `ControlPane`... – MadProgrammer Nov 23 '13 at 09:53
  • I get a compile error 'ChangeEvent evt = new ChangeEvent(evt);`, that is because `evt` variable is not declared..if you dont mind, can you tell line by line what fireStateChanged method does? Thank you very much – brain storm Nov 23 '13 at 18:46
  • when is this line `cp.addChangeListener (new ChangeListener() {...` of GamePane is executed? will it execute only if some changes happens in controlPane or is it executed anyway..how then the ControlPane fires back to GamePane when some change occurs..Is `Controlpane` is the controller and `GamePane` the model if we think of `MVC` pattern – brain storm Nov 23 '13 at 19:00
  • You need to import `ChangeEvent` from the `javax.swing.event` package. `GamePane` should register a `ChangeListener` on `ControlPane` when it constructs an instance of `ControlPane`, presumably within `GamePane`'s constructor. The `ChangeListener` will be notified when ever `ControlPane` executes the `fireStateChanged` method. `GamePane` is an "observer" of `ControlPane`, it is not a model nor is it (really) a controller, it simply observers changes in its state and reacts to them. The `fireStateChanged` method works just like the `fireXxx` methods of the `AbstractHangManModel` – MadProgrammer Nov 23 '13 at 19:21
  • It look's up all the registered `ChangeListener`s, loop through them and calls the `stateChanged` method, as described by the `ChangeListener` `interface` – MadProgrammer Nov 23 '13 at 19:26
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/41783/discussion-between-user1988876-and-madprogrammer) – brain storm Nov 24 '13 at 03:57
  • I have put in some code in the chat. somehow the HangManPane is not setting up the model. I need your assistance here. Thanks – brain storm Nov 25 '13 at 04:27
  • GridBagLayout is now hiding the secret word, I have uploaded the image in chat – brain storm Dec 03 '13 at 02:31
  • I have some questions posted in chat, can you kindly look at it when you find time – brain storm Dec 09 '13 at 21:40