I have some questions regarding the representation of the gui objects in uml class diagrams.
For example if a have a class which extends the JFrame, then i will design the UML class diagram with the inheritance symbol, but in the JFrame, i do not need to write down all of it's class variables and methods, but only those whose my class will use right??
Second how will i represent that my class will use a specific layout manager? With the association symbol, i quess but i am not sure.
Say for example I have a package named gr.mydomain.exampleproject, and I have a class extending the JFrame.
Is the following approach correct or do I need to put the JFrame in a separate package (javax.swing)?
Yes, you must draw the inheritance symbol to the JFrame class, but leave the JFrame class empty, don't put any fields or methods in it. Everybody knows or can look at the API to see what JFrame contains. Besides, you would fill up the space with the multitude of methods present in JFrame.
Do it like this:
As for layout managers: I believe the dependency relationship is the correct one in this situation. The association relationship would be correct if you would call methods on the layout manager's class. But you're probably just doing something like frame.setLayout (new LayoutManagerClass ()); (a.k.a. just creating the object). In this case, it's a dependency relationship.
Related
I currently have a rather large class that extends JPanel. The class is about 2000 lines of code although it is broken up into many mostly small functions. I want to add a second mode which will render something totally different in the panel. For organization, I am thinking of simply passing the panel to another class and have the other class render the panel. Or I could just add onto the first class. What would be the best approach? The only ugliness with the second approach is that the main class would have to check what mode it is in and if it is in the second mode, it would have to pass mouse and key movements to the secondary class.
If it's something completely different, keep them in two different classes so if anyone else were to look at your code, they'll understand better of what's going on.
Is there a time when it's more appropriate to subclass AbstractBorder than to implement the Border interface when developing a custom Swing border? And vice versa?
From the example code that I've seen, it seems quite arbitrary.
For clean OOP you should implement the Border interface. But, if you do not to plan to extend any more your new Border class with new classes that inherit from your Border, it is more convient to extend AbstractBorder.
AbstractBorder makes part of Swing to make your work easier. So use it, but do not make it the base of a class hierarchy.
Sometimes when Java has an interface XYZ and a class AbstractXYZ the class does quite a bit of work and leaves you just the bare minimum to implement (e.g List and AbstractList). Sometimes the abstract class just provides a do-nothing implementation (e.g. MouseInputListener and MouseInputAdapter).
AbstractBorder is more of the latter case; it doesn't really help the implementation of Border but it does provide some helper methods which (AFAICS) are of more use to the component 'hosting' the border than the border itself.
So, I would say it probably is a bit arbitary which one is used. I'd recommend using AbstractBorder anyway, there's no reason not to (unless you need to derive from another class of course.)
#PeterMmm, why shouldn't you use it as part of a hierarchy? A lot (All?) of the standard Swing borders derive from AbstractBorder.
I am writing a code that involves composite pattern and would like some clarification. I have Super Manager, a Main Manager and Ordinary Manager and they are in a descending hierarchy with the Super Manager at the top.
I would want the Super Manager to be able to give Main Manager some money and Main Manager to be able to give Ordinary Manager some money. The problem I have is I don't want Main Manager to be able to give Super Manager some money and I don't want to use instanceof to ensure that, since it defeats the purpose of Composite pattern.
My Main Manager and Ordinary Manager extend an abstract class called gradeManagers while my Super Manager has an array list to be able to to add components of type gradeManagers.
It doesn't sound like your hierarchy is a great fit for the Composite pattern. The Composite pattern is meant to allow a collection of objects to be treated in the same way as individual objects. (Think of parts being bolted together. Sometimes you want to think of a sub-assembly as a single part that can be bolted together with other parts/sub-assemblies. The sub-assemblies are the composites.) If I understand what you are trying to do, you don't have a collection of Manager objects that you want to treat as another Manager.
Nevertheless, whether or not you use Composite for this, I suggest adding a property (let's call it depth) that increases as you go down the hierarchy. You can then use this to implement your business rule: a Manager can only give money to another Manager of equal or higher depth. This allows you to code in a way that avoids any notion of object class.
As it has already been mentioned by Ted Hopp, this doesn't sound like something where you'd use a Composite Pattern. This just sounds like a case of polymorphism.
Composite Pattern should be used when you want a group of items to be treated as one. Consider a drawing program where you can place shapes on a screen, this could be triangles, squares, etc. Now, consider a functionality where you are able to change the background color of those shapes. If you wanted to change the background color of multiple shapes, you'd want to do something like this
interface Shape {
public void setBackgroundColor(Color c);
}
And in your actual implementation code:
for (Shape s : selectedShapes)
s.setBackgroundColor(c);
Instead of doing this in the code, you could use a composite pattern. This allows your implementation code to be completely oblivious to the fact that the "shape" you want to edit is actually multiple shapes, and allowing your application to treat it as any other shape.
class CompositeShape implements Shape
{
public void setBackgroundColor(Color c);
for (Shape s : Shapes)
s.setBackgroundColor(c);
}
class TriangleShape implements Shape { ... }
class SquareShape implements Shape { ... }
I would extend #Ted Hopp's answer and suggest that instead of depth you could use grade. This might be closer to the domain you are working with. Since you already pointed out that you do have grading managers this may be an elegant solution.
Hope that helps.
To illustrate my problem, let's say I have an instance of Thing which has two text properties - 'foo' and 'bar'.
I want to create a Panel to edit instances of Thing. The panel has two TextField components, one for the 'foo' property and one for the 'bar' property.
I want to be able to call setDefaultModel() on my Panel with an instance of IModel<Thing> and for the TextField components to reference this model. How best to achieve this?
Should I override the Panel.setDefaultModel() method to also call setModel() on the two TextField components? Or perhaps create anonymous ReadOnlyModels for the TextField components, overriding the getObject() method to retrieve the object from the containing Panel's model?
Neither of these seem very elegant to me, so I was wondering if there's a better way?
You can use a PropertyModel for the textFields. Pass the IModel<Thing> into the constructor of the PropertyModel with foo as the property name:
add(new TextField("fooFieldId", new PropertyModel(thingModel, "foo")));
The PropertyModel will figure out that the thingModel is a Model and call getObject().getFoo() etc.
This assumes the IModel<Thing> instance doesn't change, only its underlying object which can be changed calling setDefaultModelObject.
Maybe I'm just missing the point, but I can't find a Panel.setModel() in the JavaDocs of neither 1.4 nor 1.5. If it's something you implemented maybe you could change it not to replace the model object but to call model.setObject() instead?
Disclaimer: Can't really check right now, cause there is no wicket at work and my home machine suffered a video card breakdown earlier...
Maybe this would help?
public abstract class AbstractWrapModel<T> extends Object implements IWrapModel<T>
Simple base class for IWrapModel objects.
See IComponentAssignedModel or IComponentInheritedModel so that you don't have to have empty methods like detach or setObject() when not used in the wrapper. The detach method calls the wrapped models detach.
Till now, I have developed simple swing applications so there was no need to break the GUI code into diff. classes but as this application is going to be very large, I decided to break the code into diff. classes so as to make the code more manageable.
But before proceeding, I have some doubts in my mind which are as follows:
Brief description of GUI
It will have a main JFrame (MainFrame). On that a JPanel(MainJPanel) is set whose layout is to be CardLayout. It will contain 25 cards (each card is in the form of JPanel which contains its own swing components).
Q1. I have decided to make 25 classes (each for one JPanel card). Is it correct approach?
Q2. If the above answer is correct, then how can I write code of xxxxActionPerformed() methods of buttons which are on those cards (25 cards) as these methods need access to the object of MainJPanel
e.g.
public void buttonActionPerformed(ActionEvent evt) {
java.awt.CardLayout c = (java.awt.CardLayout) mainJPanel.getLayout();
c.show(mainJPanel, "card1"); // card1 is this card
mainJPanel.updateUI();
}
I googled for swing examples but almost all of them shows the use of diff. swing components. Can you also please suggest me a link that shows some swing examples that contain GUI codes in diff. classes.
Q1) That sounds like quite a lot of classes. While it's possible that each class has distinct functionality I find it more likely that you could combine some of those into more common classes. For example instead of YellowCard and BlueCard you could simply have ColorCard where color is a parameter.
Q2) Model View Presenter (MVP) and Model View Controller (MVC) are two (or one, depending on your view) common design patterns which help design GUIs so that everyone has the data they need.
More specifically, you might not need all cards to have a reference to the parent panel. For example, if you have a BurgerPanel which allows the user to order burgers and a StatusPanel which shows how many burgers have been ordered you can communicate between them as follows...
Create a StoreStatus object and pass it to both BurgerPanel and StatusPanel. When the user orders a burger with burger panel it updates the store status. The store status notifies the StatusPanel of this update via the observer pattern and then the StatusPanel reflects the change.
UPDATE: In regards to your specific example you would either some kind of reference to the parent class or you could notify it of updates with the observer patterns. (The advantage of the observer pattern is that any changes to the parent class couldn't create changes in the child classes.)
I would say you are correct in creating a class for each card. This is a logical way to split up the code.
If you need to reference the MainJPanel then simply pass it into the constructor of each card class and keep a reference to it.