My main "Game" class starts up a simple GUI - a JPanel with a couple of buttons and a TextArea. The TextArea will be used to display status messages.
In addition to loading the GUI, the "Game" class creates several "Player" objects each running in their own thread. I want each "player" object to be able to write to the TextArea when certain events occur.
The way I would choose to to this is to have the main 'Game' class publish a public "setStatusMessage(String)" method. Then I would pass a reference to the Game object to each of the 'Player' objects, so that they could call (e.g.) game.setStatusMessage("my status message").
This all sounds very obvious, but in an application where there are long chains of created objects, does this mean that I will have to pass the reference to the gui object all the way down the chain ? Is there a better way to do this ? An established design pattern that I could implement ?
Thanks for your reply Jeff, however I don't see the relevance of the MVC design pattern to this problem. Perhaps that's just my lack of knowledge though.
Also, the Observer pattern tends to be used to notify MANY objects when ONE object changes its state. My problem is the other way round - i.e. ONE object (the "Game") being notified (with a string message) when MANY objects ("Players") change their state.
Joined: Sep 16, 2005
In the Observer pattern the subject can have *any* number of observers - 0, 1, N - and an observer can observe multiple subjects (again, any number), so the pattern is quite flexible. I was thinking in your case that the subject was the game and the observer was the GUI. As for the player, it either maintains a reference to its game and tells the game when it changes state, or whatever object causes a player to change state also calls a game method to tell the game about it.
Joined: Aug 27, 2005
Many Thanks Jeff. I suppose the Observer pattern does work equally well whether it's 1 to n -or- n to 1. I've only really thought about it from the point of view of 1 to n.
This is more or less what I was proposing in the first place i.e. I pass the reference to the Game object to each Player object during construction. That way, each player can call game.setStatusMessage method.
Look at SwingUtilities.invokeLater() or invokeAndWait(). If your players trigger updates from other threads, you'll need those to update the GUI correctly. Before I learned about them I had panels that would only update if I resized the window or clicked buttons.
BTW: Observer's value is in decoupling. You can create a little WantsToKnowWhenItHappens interface with a ItsHappeningNow() method, implement it on the main GUI and make your Player use the interface. That way the Player only knows the listener implements the interface and never knows whether the listener is a GUI component or some other intermediary. Give the interface and method really good names, better than Observable or my junk and they'll tell readers a lot about the game. Let me know if that was just so much gobbledygeek or if it made sense.
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Joined: Aug 27, 2005
Thanks Stan, That did make sense. I think I'll be able to solve this elegantly now.