Question

I'm trying to get a grasp on a couple concepts. Lets imagine you have a JFrame and in that JFrame there are two panels, we'll say left_half and right_half. If I click a button in right_half, I want something to change in left_half. The issue is that the right half doesn't know the left half exists. So, you could tell the Frame, but technically neither panel knows the Frame exists either, right? The Frame can change the panels, but panels can't change the Frame, or so it seems to me.

So, I pass a reference to the Frame into the panels. Now the right_half can call Frame.setVariable(data) and the Frame can, from that same method, say left_half.setStuff(data). That just seems wrong to me and I have been looking for a way to do it without passing references up and down the hierarchy.

Next, someone says "That's why Observable exists!!" Cool, I think to myself. I then found many confusing examples of how to use Observable that didn't help at all. Finally I see this one, which makes sense. http://www.javaquizplayer.com/blogposts/blogpost7.html However, it has this: "observable.addObserver(mainWindow);" mainWindow is the equivalent of Frame in my example above, and it had to pass a reference to attach the Obserable to! So even with Observable, I have to pass references down the hierarchy?

It just seems wrong. If it's not wrong, that's fine... I can do it this way. However, my question once all that back-story is finished is simply this: how are you supposed to pass data between two panels? I'm okay with abstract answers if they're in plain language, I'm okay with code samples if they're short and easy to follow. I'm not a pro Java coder, I can't just search through 29 API pages and 1400 lines of code and just suddenly understand how it works... yet. I'll get there.

Was it helpful?

Solution

The observable pattern (in the form of event listeners) is OK and is good practice. You see, even though RightPanel knows someone might be listening to all its events, it does not know who is listening. Well, technically, it could go through all its listeners and use reflection to find out who they are; now, that would be bad practice.

As it is, RightPanel knows someone might be listening to it, and that's all. Components are always aware someone might be listening, since the whole Swing is based on it. What matters is that RightPanel compiles without LeftPanel (or frame), and is completely decoupled from it, except via the listener interface. Not only cool, but standard.

As a side note, your class structure does not have to mirror your nesting panel hierarchy. Depending on what you are doing, it may be entirely fine to control behavior of both left and right panels from inner classes within Frame. (Personally, I'd use a JPanel, not a JFrame, since it allows for more flexibility, but this can be easily refactored). Otherwise, you risk splitting your View/Controller into too many closely coupled classes, and that would violate encapsulation and cause a lot of boilerplate code. Normally, I don't code big fat classes and try to refactor them into smaller ones; Swing is usually an exception. Better one big fat class than a maze of densely coupled classes. Unless of course you have a reusable component or some piece of functionality that can be clearly and intuitively decoupled; not just a couple of buttons or checkboxes that have no meaning in and of themselves. The simple fact that some subcomponents are situated within a certain panel in a component tree should not be a major factor IMHO.

For that matter, I usually don't nest JPanels; I use MigLayout and make all components into siblings. Matter of taste! I'd just encourage you to check out MiGLayout first and see whether you like it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top