In C#, there are observable collections. In Java how do I represent a list a models? Suppose I have a model Item. I want to show users a list of Items. Do I create a ItemsModel (notice plural, encapsulating an ArrayList<Item>) then in my ItemsView bind (listen to property change events) to that? This model will also need to listen to PropertyChange events from its underlying Item. Is this the right way of implementing this? Is there a better way?
A possible solution could be the Eclipse Databinding. It let's you create a binding from your POJOs to certain SWT Controls. For your special case with Items, you could use the Master-Detail Binding mechanism, for an example see http://wiki.eclipse.org/JFace_Data_Binding/Snippets#Master_Detail
Depending on the source of your domain model, you could consider changing it to use Eclipse Modeling Framework (EMF). EMF have complete a notification framework for all changes made to the model, which makes it easy to use and bind to. Eclipse Databinding - as mentioned by Tom Seidel - also bind to EMF.
Related
I'm trying to do the OOP approach in all my xPages. As expected I'm facing several issues, but also have tons of advantages doing so.
My question is related to Views (Repeat controls). I am loading a List<myCustomBean> for my repeat controls that contains all available objects of type myCustomBean and display each myCustomBean the way I want in a Bootstrap table row. That works all fine.
I'm able to sort my List with URL parameter sortedBy=MySortColumn with my own method. - Problem 1 solved.
How would I approach a Categorization in my Repeat Control? So I could easily sort the beans by the Cotegory, but how would I display it, incl. expandable and collapsible twisties? Maybe there is a Custom control that I can use? Or a Control of the Extension Library?
Or do I have to build everything from scratch myself?
Any advice is much appreciated.
The Data View control is probably the best. Like the View Panel or Data View, it's a extension of the Repeat Control. But it has much more flexibility that the View Panel and allows much more configurable layout than the Data View. It has a categoryColumn property, but that's designed for binding to a dominoView datasource. But there is also the categoryRow facet which can be used.
Essentially, using a dominoView component is already using OOP programming. Your repeat is using List<myCustomBean>, dominoView returns List<DominoViewEntry>. Properties on the dominoView are used to interrogate the underlying View object within the database and return only those ViewEntry objects from the ViewNavigator or ViewEntryCollection that are required. It wraps the ViewEntry as a DominoViewEntry object for just a selection of those, based on the rows property of whatever uses the DominoView.
As someone who built a subset of that functionality for use from Vaadin (see my XPages to Web App blog series http://www.intec.co.uk/tag/xpages-to-web-app-tutorial/), within XPages I typipcally use the dominoView object unless I'm extracting a small subset of ViewEntries / Documents. When I use ViewEntryCollection / DocumentCollection, I rarely wrap, preferring to let XPages optimise retrieval rather than re-develop that optimisation myself.
I have read about MVC but am having doubts on how to implement the concept in Java with Swing. Here's what I'm going for:
The model:
ListOfThings contains a Collection of Thing objects.
The controller:
Controller instanciates ListOfThings and populates it with a "add" method (internally creates a new Thing and adds it to the Collection)
The view:
A Swing interface with a ListOfThingsPanel which will contain ThingPanel components to represent the model. Both extend JPanel. ThingPanel contains various components meant to display the data of the Thing it's linked to.
It also has a button which adds a new (empty) thing to the list.
The click event calls the Controller's addThing() method which asks ListOfThings to add a new Thing to its list. ListOfThings has an event/listener system and ListOfThingsPanel listens to it to know when it should refresh the view.
Am I properly following the MVC concept by doing it like this?
Update:
I'm still learning Java but I have coding experience and would prefer to learn the theory and attempt it by my own means before using premade frameworks. While I'm aware Swing implements the MVC pattern, I have read it does it in a specific way (View and Controller combined) which might not be the best and not applicable in other circumstances. I'm a bit wary until I can make sure "Swing MVC" is not different from "MVC", or that the differences won't impact my understanding of the underlying ideas.
One thing of import to me is to learn to really separate the model from the view to allow me to ultimately create various views of various types (Swing but also console or update to JavaFX for example) This is why I'd like to avoid anything Swing specific outside of the view part itself.
While the Swing framework already implements a form of MVC (explicit models; JXyz & UI classes = controller & view), this strict separation is rarely used on application level and looks rather weird.
To start I suggest to follow the following design:
implement the client-side business logic with POJOs
wrap the POJOs with custom Swing models where needed (ListModel, TableModel)
Use a GUI builder to design the GUI
Use the Mediator pattern to listen for events (a custom subclass of JPanel listens for events of its children and updates other children or fires own custom events if needed)
If you want to go a step further, use a RCP such as the NetBeans Platform (very recommended).
Edit:
And here is the article explaining MVC in Swing:
http://www.oracle.com/technetwork/java/architecture-142923.html
I have a number of GUI classes that is accessing the same information object which is set from its constructor.
Each GUI class displays the gui information object in a different way.
Is it better to initialise the object each time in the constructor or just add the object to memory and use it each time a GUI class requires it ? Does either method fall into a design pattern ?
Before even reading up on specific object design patterns, a good starting place is to read up on the MVC (Model View Controller) pattern. It's probably the most commonly used architecture pattern out there, and a google search will bring up tons of good material (Wikipedia would even be a good place to start in this case)
It's used to address the problem you've hinted at, where your various display logic has to frequently access the same information holding logic. In an application which uses an MVC architecture, your code is (more or less) separated into three categories, code which displays information in a UI, code which holds (or models) information, and code which controls the flow of the application and application events. MVC applications commonly use listeners and other event design patterns, like the ones mentioned above.
Take look at dependency injection, listeners and event bus.
I would suggest dependency injection, there are a lot of frameworks out there. My favorite is guice but YMMV.
How about using a strategy pattern?. Basically just define a set of classes that inherit from the same interface such as
public interface GUIBehavior {
}
//Set of classes
public behavior1 implementse GUIBehavior...
//In the clases that display the information simply set an attribute for the behavior
private GUIBehavior myCurrentBehavior;
I'm already using Guice for the data model of my app, and so far I'm quite happy with it. However, the GUI part is about to become a Big Ball of Mud. I find it hard to use Guice here, because Swing components and models are tightly coupled, and often force a certain initialization order.
My application consists basically of a header with a lot of filters, a central and quite complex JTree component, and a lot of actions (e.g. from a JPopup), menus, dialogs, wizards etc. The main problem is that I have a lot of coupling between the components and actions (e.g. complicated validations, tree updates...). Could you give me some advice how to structure that GUI with Guice?
I'm aware of libs like GUTS, but the documentation is really thin, I'd rather avoid to add another dependency to my project and to learn another API (e.g. I don't know the Swing Application Framework).
I'd rather suggest a proper MVC, even better Presentation Model - View - Controller. Separate your code properly and Guice will fit in naturally. For example:
View classes should have a building part which draws the static content (labels, the tree, buttons, etc) and updating code which reacts to changes in the Presentation Model. All the action listeners should invoke some code on the controller. Both the Presentation Model and the controller should be injected by Guice, like all the other dependencies.
This organization would allow for easy testing with replacing the View with some testing code which will listen to changes in the Presentation Model and invoke actions on the controller.
I would advise to look at Guts-GUI.
It is a Swing UI framework based on Guice dependency injection model.
I think the problem is probably the overall architecture. You probably want to see if you can refactor the application to be simpler and more modular. Like Boris recommended, I would also suggest using the Presentation Model pattern - search for Martin Fowler and Karsten Lentzsch - and the JGoodies library.
For the problem with Actions, see how the Swing Application Framework and Netbeans Plaform handle them. For example, if an Action is used in both a view and a menu, you might want to make it available through a global map.
We have recently started on GUICE with swing. Here's what we have done which may be of help to you.
a. When you want to inject a model into a table/tree you could inject a model provider instead and do a provider.get() to get the model in the contructor.
for example
public class Mytable extends JTable {
public Mytable(Provider<MytableModel> modelProvider) {
this.setModel(modelProvider.get());
}
}
b. You could make a model generic and make use of the same model in different tables.
c. The model could have a handle to datasource which could be injected by a factory where necessary with assisted inject. Number of examples available in stack overflow.
d. Your model could be a flexible data structure which uses model to return the relevant cell/leaf/other value.
e. When you have actions, you inject actions in your component builders and attach them to relevant components.
f. Use #Singleton annotation where you have a shared object such as model injected in 2 different objects, such as action and the component.]
g. Use custom scope when you need to use number of instance sets of objects. Custom scopes are great for this as it keeps the code really clean.
Hope the above helps...
Does the JGoodies list binding support binding list contents to a list object in the model? I know I can add listeners to the list model and domain model and coordinate changes between the two fairly easily, but I wasn't sure if JGoodies would do that. I could only find list binding that dealt with list selection events.
I'd suggest you use GlazedLists. It's really easy to use and works great.
One issue is you have to use one of their classes that implements EventList; you can't just bind a list model to a pre-existing List.
It looks like the LinkedListModel and ArrayListModel do this. I overlooked those before.