2

So I've been trying to see how I could best structure my code, because I have an intuitive feel that there must be a better way to achieve what I want without passing around a single object to nearly every UI class in the project.

The project I'm working on has a class RhythmWheel that extends JRootPane. The constructor then goes on to create all the components that form a RhythmWheel. For example it creates an instance of ControlPanel (which extends JPanel) and adds it to itself.

However ControlsPanel needs to have a lot of knowelgde of things that are defined in RhythmWheels like the number of wheels that are currently selected. Currently the constructor for ControlsPanel takes a RhythmWheel as an argument, and then keeps a reference to it. It uses this for things ranging for component a JFileChooser should be parented to to, and as an argument to a function that writes the revelant state of the application to an XML file.

It seems wrong to me that I'm passing around a main component across so many classes. I thought about design patterns, and figured that a singleton might be a solution to this. However I have read numerous times that singletons are evil and are an anti-pattern. I guess the MVC pattern might help, but I'm not sure how I'd implement that in Swing. And most recently I came across Dependency Injection as a possible solution.

I'm a little lost as to what I should be doing, or if I should be doing aything at all. If you'd like to glance at the code I'm working on, you can see it at https://github.com/vamega/RhythmWheels so any advice on how to proceed would be great.

Varun Madiath
  • 3,152
  • 4
  • 30
  • 46
  • You might see if this [example](http://stackoverflow.com/a/3072979/230513) offers any insight on MVC. – trashgod Mar 17 '12 at 05:40

2 Answers2

1

if everything needs a reference to RhythmWheel then it sounds like RhythmWheel is awfully complex. maybe you can break RhythmWheel into a collection of components that (hopefully, and likely, since GUI should reflect logical structure) correspond to particular parts of the GUI?

also, why do all the GUI components keep references to the RhythmWheel (or the appropriate sub-component, if you refactor as described above)? i haven't done much spring programming, but i thought the idea was to structure things round an observer pattern. in that case, the gui components should be registering themselves as observers on the wheel components, so that they can update when the wheel changes.

and yes, this is mvc. the wheel components form your model; the gui is your view. what is less clear is what the controller is. i suspect that it is the high-level wheel.

so, in summary:

  • the wheel is composed of sub-components
  • the wheel has high-level methods that reflect what you can "do" to it
  • the wheel's high-level methods are what are called by actions in the view
  • the wheel's high-level methods make changes to the wheel's sub-components
  • the wheel's sub-components, when they change, inform the model, which updates

only the input parts of the view need references to the wheel; the display parts are triggered via callbacks registered with the wheel sub-components.

(to answer the original question directly, i don't see anything so bad in passing around a wheel instance, but as i suggest above, it might be better for it to "fragment" into different components as it gets "lower" into the GUI).

andrew cooke
  • 45,717
  • 10
  • 93
  • 143
0

I don't see what's wrong with using singletons. A control panel sounds like a prime candidate for a singleton. Why would have you more than one? Same goes for the others. Anything your currently accessing in ControlPanel from RhythmWheel can be exposed through getters and setters.

Unless there's a model/view separation that you would like to decouple or a view that needs to observe model updates, I wouldn't use MVC.

blackcompe
  • 3,180
  • 16
  • 27
  • I think that decoupling the model from the view would bring about other advantages as there are things other than the UI that I'd like to notify when things change. – Varun Madiath Mar 17 '12 at 06:56
  • That's always a a good practice. From what little I saw of your code, I wasn't able to tell if there was a model. If you've got multiple view components that respond to a single event, you should use the Observer pattern. – blackcompe Mar 17 '12 at 07:23