Why Swing Components have .getParent() method, Is it violated Object Oriented Principles? - java

I am working on Object Oriented Design Principles and Heuristics.
In the remarkable book named Object-Oriented Design Heuristics By Arthur J. Riel (1996) I see this heuristic:
Heuristic 4.13: A class must know what it contains, but it should never know who contains it.
Based on J.Reil, The main reason is reusability.
But in Swing Structure, we can access directly to the reference of Parent object.
for example: label.getParent()
So my question is:
Why swing components have .getParent() method?
Which Object Oriented Priciples or Heuristics are behid of existing this method?

Two things here: no rules are cast in stone in software engineering. It is always about balancing different aspects that are somehow competitive.
Then: the main purpose of UI components is (surprise) to be used in UIs. And typically any UI element belongs to exactly one parent. You can't have the same table showing up in two windows (maybe the same data, but not the UI table objects!). And from there: getting to the parent of a UI component is something that you need all the time. UI elements are always owned - and it is much more convenient when you can go up and down easily.
Long story short: I think you are looking at a very special case here - where it simply makes a lot of sense to deviate from a rule written in some book.

Disclaimer: I haven't read the book in question, so I can only speculate on what the author meant.
But my surmise would be that what is intended here is that the class should not change its behavior based on the type of the class that contains it. So, a Button must not behave differently when it's in a ScrollPane than it does if it is in a JPanel or a JFrame.
But the hierarchy of components in the UI is part of their responsibilities. They are in a tree structure, and so they not only maintain links to one another, but they have accessors to allow client code to navigate that structure. Now, you could have a structure where only the parents had links to the children, and not vice versa, just as you could have a singly-linked list. But to have a doubly-linked list, where each node has a pointer, not only the the node after it, but also a pointer back to the node before it, is not a violation of object-oriented principles, and neither is it a violation to have a doubly-linked tree structure where the child nodes also have pointers that allow navigating up the tree, from children to parents.
We must ask ourselves, how would knowing who contains it impair reusability? Why would knowing that make the class less reusable? Now, if it changed its behavior based on who contained it, that would do it. You could not just take the class and use it somewhere else, because it might not do what you expect it to do. But merely maintaining the links doesn't harm reusability.
(I would note that, if you're going to add and remove components from the hierarchy, there has to be some care taken in their API so that when you tell one of them you're severing the link, both of them can update their state. But that can be handled as part of the API design. As long as that was done up front in the first version so that it's part of the contract of all classes that are written to be part of that component hierarchy, it would not pose a problem.)

Related

JList and ListModel design pattern advice

I am building an application which is basically just a GUI for displaying and editing one single object. Since the class for this object was created with JAXB, it is basically a tree with many Strings and integers as children, but there are also some List<E>s. For each simple child JAXB provides a getter and a setter, but for all lists only a getter is provided, since it gives a reference to the internal list, which can now be modified.
Since I need to display every child (and branch for that matter) in a separate swing GUI component, I need these views to handle some data. According to my current knowledge about the model view controller design pattern, I should strictly separate the model from the view. Following this, it would be a bad idea to let a JList operate directly on an internal list of my base object. (Actually doing so would be a pretty easy solution to my specific use case, but since additional functionality might be added later on, I think I should refrain from this idea.)
Then I started thinking: If I do not let the components work on the list directly, I have to make them use a copy of the original. But since I cannot set the original list to a new one returned by my GUI component, I have to copy the items another time when saving the view data to my model. Also, it would not be wise to hand out references to internal lists of a custom ListModel, which would mean, that depending on the depth of the GUI structure, the list may be copied additional times.
Since I also want my application to be efficient, this does also not seem like the correct approach. How do I build this "correctly"?
Summary:
The List<E> from the original object is a reference to an internal list of
the object.
The JList displaying the list should not get this reference,
hence it must copy the list.
Getting the list from the JListshould not yield in a
reference to the internal list either, hence it must be copied again.
Saving the list to the original object must copy the list a third
time, because the original object does not have a setter method for the list. (see
above for details)
Is my grasp on this correct? How do I build this properly and make it efficient?
P.S: Adding setter methods to the original class structure is not an option!
was created with JAXB, it is basically a tree with many Strings and
integers as children, but there are also some List<E>s. For each
simple child JAXB provides a getter and a setter, but for all lists
only a getter is provided, since it gives a reference to the internal
list, which can now be modified.
see
JTreeTable
JList (unmodifiable), better could be JTable (with / without JTableHeader) in JTree
All of the components suggested by #mKorbel provide some kind of selection listener that will allow you to loosely couple a selection in one panel to the selected item's display in another. FileBrowser illustrates a TreeSelectionListener; Outline can have a ListSelectionListener, shown here; etc.
Addendum: In this related example, DisplayPanel listens to an adjacent TableModel, which it can query to update a model in one of it's own components. Note that each model is loosely coupled to its respective view. Common notification mechanisms are mentioned here.

What's the best method to traverse the Swing DOM?

In a browser if I'm using javascript it's fairly straight forward to traverse the DOM. Unpacking it from the top down is just a series of calls, and finding individual elements is easy because of id# tags.
Swing components have a treelike structure similar to HTML. What's the best methodology for traversing that structure to find objects inside of it? Or should I simply stick to creating local field references to the objects that I care about?
Assuming you have a user interface that has data in it, and some code that's interested in querying those components to find out what their state is, how would you manage "finding" those components in the Swing DOM?
A HTML DOM is a tree data structure, which doesn't provide much behavior, and that uses node types that are not under your control.
A Swing tree of components is a tree of rich objects, containing objects of types that you create, and which should provide the behavior you need. You should apply the OO principles to the elements of this tree (panels, etc.): encapsulation, law of demeter, composition, etc.
You shouldn't have to traverse a tree of Swing components to find the one you want. This would be a sign of poor design and lack of encapsulation. The elements of the tree should collaborate, reference each other, call appropriate methods to do their job.

How can I avoid passing around a single instance of a top level component to all my subclasses

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

How to determine and cast to specific object of composite while using it?

I would like to have a composite structure which is build from JSON. Each element can has only one type of children - so a group can contain only groups or only leaves. Then based on this tree I want to draw graphic user interface component, which will render diferrently and run different actions due to the type of itself (group or leaf).
The question is how to determine what to render and which listeners to attach on drawing. The tree is only a model, so it should not contain methods to do the graph or controlling.
Is it a good or bad pratice to check if it is instance of something and cast component to to right type and then do the right set up?
What about having a enum and getter to determine it?
I know answers that will work but I want to hear about good pratices.
Is it a good or bad pratice to check if it is instance of something
and cast component to to right type and then do the right set up?
Personally I think this will break the pattern.
Accordingly to wikipedia:
When dealing with tree-structured data, programmers often have to
discriminate between a leaf-node and a branch. This makes code more
complex, and therefore, error prone. The solution is an interface that
allows treating complex and primitive objects uniformly. In
object-oriented programming, a composite is an object designed as a
composition of one-or-more similar objects, all exhibiting similar
functionality.
Composite is a pattern that help you to use both container and leaf as the same type.
Look this diagram.
I suggest you to add and abstract draw method to the component class and let its subclasses implement it. Leaf will have a different implementation than Composite. This way a client class traversing your tree doesn't need to be aware if a node is a Leaf or not, but can simply call draw method on it.

How to make a design "loose coupling"?

I'm making a simple 3D CAD software. in the class diagram, many objects need to distinguish with others by (x,y,z). I create a class so-called "Position", but the problem is it looks highly-coupling because many classese work with position.
Any ideas?
It is not a problem per se if a type is used by many other types. In your case, graphical objects obviously (usually) have a position so the coupling looks natural and reasonable from the perspective of the domain model.
Also, the Position class is probably going to be a fairly low-level class whose interface (and probably implementation too) is not going to change very often in the long run. So there is not much chance of such changes breaking client code.
First let me say after 12 years that your design is not bad. Assuming that the positioning logic of your classes shall be called from outside, all your classes need to have and offer this logic. So it is part of the interface and you must bring the functionalities in. And this means, you must depend on it and there is a coupling. The coupling is not between your objects. So it is not as bad.
But there are always alternatives. It is known that inheritance establishes a very tight coupling. Consider for example that the positioning logic is only called internally in your class. Then you don't have any benefit in inheritance. You could as well have another class (let us call it Position). And instead of deriving from this class, you integrate an object of this class. And whenever you want to do something with the position, you call the corresponding methods of this object.
This alternative looks like a nonsense change. Why should you do this? But let us have a look at the consequences. Assume you have a class Circle. Circle has such a position object as proposed above. (By the way, see the wording "has a position" instead of "is a position". The "object-and-composition" solution seems to be quite natural.) Somewhere in a file X of your code you may have created such a Circle. And now you decide you change the positioning logic. In X you don't have to worry that this has a side effect, because the interface of Circle has not changed. It is just one object inside of Circle that has changed. That is just an implementation detail. In contrast if you would have used inheritance, you cannot just change the base class without looking if this has a negative effect to X. So this "object-and-composition" solution has actually reduced the coupling between X and the positioning logic.
You can even reduce the coupling further. With the object-and-composition solution, whenever you change the positioning logic, you have to check all your classes if this has an effect. But what about using an interface for Position. Your classes don't see an object of a type Position, but an object that fullfils an interface Position. And the actual positioning logic implements this interface. This way most of your classes' code has no dependency to the implementation of the positioning logic.
That is not the end of the game. There is still a coupling, because your classes must somehow create the position objects. So at least the constructor must go into detail and for example pass x,y,z. But what if you use something like a factory for this purpose, so that your objects just get the position without even knowing how these have been created. Then you are absolutely flexible. You can use your classes in completely different situations. For example in a two dimensional coordinate system. There is no coupling between your positioning logic and your classes any more.
I hope you see that all these options exist. I suppose in your example this is a bit over-engineered. But your question was how to reduce the coupling. And there are always ways. Combinations are of course possible. For example you can have the object-and-composition and make the position object public in your base class. But then I would ask if not inheritance would have been the better option?

Categories