JavaFX 8: Separation of model/domain from view - java

I am just learning JavaFX 8. It seems if you want to display something in a control, say a TableColumn, you need that something to be an instance of ObservableValue, for example, a SimpleStringProperty.
So, in the commonly used Person object, I might have a SimpleStringProperty for "firstName", and then I would be able to use that as the value of TableColumn, like this:
TableColumn<Person, String> firstNameCol =
new TableColumn<Person, String>("First Name");
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
But, Person is what I would call a "domain" class -- something that my model would freely refer to and use. I don't want my domain and model layers to be aware of / dependent on the fact that the application is displayed using JavaFX.
Am I right in thinking that the model/domain should be kept pure in that regard? If so, what is the best way to accomplish that using JavaFX? E.g., should I write adapter classes somehow for my domain objects to present them with ObservableValues?

It is certainly wise to keep your domain model pure, and not tie it to any specific framework as you may need to use those objects in other contexts (database storage, exposing them in a REST API, doing batch processing, etc.).
Changing your domain model to use JavaFX properties would add a lot of extra baggage to those classes that you need to avoid in other scenario's.
JavaFX however does have a standard way of dealing with this situation so you can connect your domain model to its controls easily, and it works in a way you already suggested, using adapters from its javafx.beans.property.adapter package.
Using these adapters however won't make your controls respond to values changing in your domain objects like they would with SimpleStringProperty for example.
It will depend on your requirements if that is a problem, if it is however you may consider modifying your domain model objects to add PropertyChangeListener support. This is a relatively light weight change (vs. full JavaFX Properties) and would not make you depend on JavaFX (only on java.beans which is less problematic).
See this answer for a thorough explanation of how to use domain model classes in JavaFX directly: JavaBean wrapping with JavaFX Properties

Why do you want to avoid using any JavaFX class at all?
JavaFX Properties (found in the javafx.beans.property package) are just an extension to the regular JavaBeans properties.
They are part of the JavaFX Properties and Bindings framework, which doesn't depend on the JavaFX Toolkit to have its functionality implemented, nor does it require your application to leverage the JavaFX UI classes in order to build its graphical user interface.
It can therefore be used as a standalone facility anywhere in your code, without having to worry about the model/domain being coupled to this particular implementation of the view.
You should consider the JavaFX Properties and Bindings framework a general utility that is inherently indipendent of the implementation of the view due to its nature, just like is any other general-purpose library (e.g. Guava). You could, for example, switch to a Swing application at any time, while still keep using it.
But if you still prefer to not leverage its functionality when possible, then there's a case when you can actually do so:
if what's being presented isn't going to change (e.g. the state corresponding to the table model in your domain class is immutable), and standard property getters are present, then, as per the PropertyValueFactory documentation:
There is fall-through support for attempting to call get<property>() or is<property>(). If a method matching this pattern exists, the value returned from this method is wrapped in a ReadOnlyObjectWrapper and returned to the TableCell. However, in this situation, this means that the TableCell will not be able to observe the ObservableValue for changes.
Avoid adapters; they are meant to be used with legacy code only that cannot be altered in any way.
Related Posts
JavaBean wrapping with JavaFX Properties
JavaFX Properties Design
Does the use of ObservableList in JavaFX go against Model-View-Controller separation?

The next version (8.6.0 in active dev) of JRebirth will allow to generate these FXJO (javaFX Java Object) from POJO (Plain Old Java Object) by using annotation processor.
Or by directly parsing an ecore file.
It can give you the opportunity to not alter your Business Model with UI related stuff like Properties.

Related

Modelling event type objects

We have an application that is composed of a number of independent components and sub-systems. We are looking at implementing a simple event logging mechanism where these components & sub-systems can log some events of interest. Events could be something like
New account created
Flight arrived
Weekly report dispatched to management etc.
As you can see, the event types are heterogeneous in nature and the attributes that needs to be logged differs based on the event types. New account created event, for example, will also log the account-id, the name of the user who created the new account etc. Whereas, the flight arrived event will be logging the flight number, arrived at, arrived from etc.
I'm wondering what is the good way of modelling the event types and the attributes.
One option is to do it object oriented way - to have an AbstractEvent that will have some common attributes (timestamp, message etc) and then create a full hierarchy of classes underneath. The flight events, for example, can look like
abstract class AbstractEvent;
abstract class FlightEvent extends AbstractEvent;
class FlightArrivedEvent extends FlightEvent;
class FlightCancelledEvent extends FlightEvent;
The problem I see with this approch is that we have hundreds of events which will result in class explosion. Also, whenever we add a new event (very likely), we have to create a class and distribute the new package to all the components and sub-systems.
The second option I can think of is on the other end of the spectrum. Have a simple Event class that contains the basic attributes and wrap a map inside it so that the clients can populate any data they want. The code in that case will look something like this.
class Event {
private timestamp;
private eventType;
private Map attributes;
public Event ( String eventType ) {
timestamp = System.nanoTime();
this.eventType = eventType;
attributes = new HashMap();
}
public Event add ( String key, String value ) {
attributes.put ( key, value );
return this;
}
}
//Client code.
Event e = new Event("FlightEvent:FlightArrived")
.add("FLIGHT_NUMBER", "ABC123")
.add("ARRIVED_AT", "12:34");
While this is flexible, it suffers from inconsitency. Two components can log the FLIGHT_NUMBER key in two different formats (FLIGHT_NUMBER & FLGT_NO) and I can't think of a good way to enforce some convention.
Any one have some suggestions that can provide a nice compromise between these two extreme options?
There is a Java event framework (see java.util.EventObject and the Beans framework) but the fundamental question you are asking is not connected with events. It is a design question, and it is this: do I use Java classes in my application to represent classes in my business domain?
It is clear that the different types of event are different "classes" of thing, but for maintainability reasons you are considering representing your business data in a map so that you don't have to write and distribute an actual class. If you take this to a logical extreme, you could design your whole application with no classes and just use maps and name-value pairs for everything - not just events. It would be a mess and you would be debugging it forever because you would have no type-safety whatsoever. The only way of finding what was in map would be to look up in some documentation somewhere what someone might have added to it and what type that object might be.
So, here is the thing - you would not have actually have gotten rid of your class definition.
You will have moved it into a Word document somewhere that people will have to refer to in order to understand what is in your map. The Word document will need to be maintained, verified and distributed but unlike the Java class, it won't be checked by the compiler and there is no guarantee that the programmers will interpret it correctly.
So I would say, if there is a class, put it in your code and then focus on solving the problems of distributing and versioning the Java classes instead of distributing and versioning Word documents.
I will mention versioning again as this is an issue if you might serialise the objects and restore them, so you need to think about that.
Some caveats:
If you are writing a piece of middleware software that routes events from one system to another system, it might be you don't need to know are care what the data is, and it might make sense to use a generic holder in this case. If you don't need to look at the data, you don't need a class for it.
You might get complaints from high-level designers and architects about the number of classes and the work they have to do in defining them compared with a map and name/value stuff. This is because putting classes (i.e., the real design) in Java is harder than putting them in a Word document. Easier, if you are high-level hand-waving type guy, to write something wishy-washy in Word that doesn't need to run or even compile and then give the real design work to the programmers to get working.
Can [someone] provide a nice compromise between these two extreme options?
No. There is no generic one-size-fits-all answer to this problem. You will have to find yourself a balance which fits the general design of your product. If you nail everything down, you will need thousands of classes. If you give a lot of leeway, you can get away with a few but you're paying your freedom with precision. See my blog post "Designing a Garbage Bin"
Do you have shared attributes? As in: Do you expect to define attributes of events like you define classes right now with very tight-fitting semantics?
That would mean you have a simple event and typed attributes (i.e. String value simply isn't sufficient). You need formatting and validation for attributes or ... attributes themselves need to be classes.
If this is the case, you can use my type-safe map pattern: http://blog.pdark.de/2010/05/28/type-safe-object-map/
Event type "explosion" is not a problem. In fact it is a desirable approach as it allows the components to be independent of one another. I wouldn't necessarily make all events inherit from a single superclass unless it gives you a lot of reusable code because it can cause dependencies to start proliferating.
I would put the event types in a separate project that will be a dependency of both the publisher and consumer.
What is your communication mechanism for these events between components? JMS? If so you could also consider making your messages XML and using JAXB.
I would definitely discount the map approach as it destroys any hope of polymorphism or any other oo niceties.

Does the use of ObservableList in JavaFX go against Model-View-Controller separation?

I am attempting a study of JavaFX because I want to use it as the GUI of my program. My question is essentially a conceptual one:
To date my program is mostly the "Model" part of the MVC pattern; that is, almost all of my code is the OO-representation of abstractions in the sense of classes, and all of that code is logical code.
Since I do not want to be the only user of my program, I want to add the "View" part of MVC so that people can easily use and manipulate the "Model" part of my program. For this, I want to use JavaFX.
In my "Model" classes I obviously use various Lists, Maps, and other classes from the Java Collections API. In order to let the users of my program manipulate these underlying Lists and Maps I want to use the Observable(List/Map) interfaces in JavaFX.
A concrete example to bring clarity to the situation:
Let's say that I have a MachineMonitor class that every 3 minutes checks certain properties of a Machine, such as if the connection is still good, the speed that the gears are turning, etc. If certain inequalities are met (say that the speed of the gears has fallen to a rate of 1 turn/sec) the MachineMonitor fires a RestartMachineEvent.
Currently I use an ArrayList<MachineMonitor> to keep track of all of the individual MachineMonitor's. Now extending to the "View" part of MVC, I want the User to be able to manipulate a TableView that displays the list of MachineMonitors so that they can, for instance, create and remove new MachineMonitor's to monitor various Machines.
So that I can keep track of what the user of my program wants to do (say, create a MachineMonitor for Machine #5 that checks to see if the turn/sec of the gears falls below 0.5) I use an ObservableList<MachineMonitor> as the underlying List for the TableView.
The easiest way to link the "Model" and "View" of my program would simply be to change the "Model" class to have an ObservableList<MachineMonitor> and not an ArrayList<MachineMonitor> but (getting to the topic of the question) I feel that this is very messy because it mixes "Model" and "View" code.
A naïve approach would be to use an ObservableList<MachineMonitor> for the TableView and retain the use of my ArrayList<MachineMonitor>. However, changes made to the ObservableList<MachineMonitor> do not affect the underlying List as per the JavaFX specifications.
Given this, is the best way to solve this conundrum to make a ChangeListener for the ObservableList<MachineMonitor> that "propagates" the changes made to the ObservableList<MachineMonitor> to the underlying "Model" ArrayList<MachineMonitor>? Perhaps put this in a class called MachineMonitorController?
This ad-hoc solution seems very messy and non-ideal.
My question is: What is the best way to retain nearly complete separation between the "Model" and "View" in this scenario?
Briefly, I don't think use of ObservableList breaks the MVC contract.
The rest, you may read or not as you wish, as it is quite annoyingly long.
Architectural Pattern Background
Observables are useful in MVC style architectures because they provide a way of feeding data back and forth between the MVC components through loose couplings where the model and view classes don't need to refer directly to each other, but can instead work with some shared data model which communicates data flow. It's not a coincidence that the Observable pattern and the MVC style architecture concept both originated around the same time at Xerox PARC - the things are linked.
As noted in Martin Fowler's GUI architectures, there are numerous different approaches to building GUIs. MVC is just one of these, kind of the granddaddy of them all. It is nice to understand MVC well (it is often misunderstood) and MVC concepts are applicable in many places. For your application you should use the system which feels best for you rather than rigidly following a given pattern (unless you are using a particular framework which enforces a given pattern) and also be open to adopting different patterns within an application rather than trying to shoehorn everything into a single conceptual framework.
Java Beans are a fundamental part of almost all Java programs. Though traditionally often only used in client apps, the observer pattern, through PropertyChangeListeners, has been, for good reason, a part of the Java Bean specification since it was created. The observable and binding elements of JavaFX are a rework of that earlier work, learning from it to build something that is both more convenient to work with and easier to understand. Perhaps, if the JavaFX observable and binding elements had existed ten or twelve years ago as part of the JDK, such concepts would be more generally used in a wider variety of libraries and frameworks than a couple of pure GUI frameworks.
Advice
I suggest considering the MVVM model and other GUI architectures.
If you want a dead-easy framework which follows a model, view, presenter style, definitely give afterburner.fx a spin.
I think the correct choice of architecture depends on your application, your experience and the size and complexity of the problems you are trying to solve. For instance, if you have a distributed system, then you could follow REST principles rather than (or in addition to) MVC. Whichever you choose, the architecture should aid you in solving the problem at hand (and possibly future problems) and not the converse. Over-architecting a solution is a common trap and is very easy to do, so try to avoid it.
Caveat
One caveat to consider is that observables necessarily work via side-effects which can be difficult to reason about and can be antithetical to the concept of isolation. JavaFX features some good tools, such as ReadOnlyObjectWrapper and ReadOnlyListWrapper, to help limit the impact (damage control if you like) on observables so they don't run amok in your system. Use such tools (and immutable objects) with reckless abandon.
Learn from Examples
For a simple JavaFX application which is built using observables, refer to tic-tac-toe.
For a good way to structure a large and complex JavaFX application with FXML based components, refer to the source code for SceneBuilder and SceneBuilderKit. The source code is available in the JavaFX mercurial source tree, just check it out and start learning.
Read up on the JavaFX UI controls architecture. Examine the JavaFX controls source code (e.g. Button and ButtonSkin or ListView and ListViewSkin) to see how concepts such as MVC can be applied using JavaFX structures. Based on that learning, try creating some of your own custom controls using the architecture that the JavaFX controls framework provides. Often, when you are building your own application you don't need to create your own controls (at least ones which derive form JavaFX Control). The JavaFX Controls architecture is specially crafted to support building libraries of reusable controls, so it is not necessarily generally suitable for all purposes; instead it provides a concrete demonstration of one proven way to get certain things done. Adopting and adapting proven solutions goes a long way to ensuring you don't reinvent stuff needlessly and allows you to build on a solid base and learn from the trials of others.
Regarding your Concrete Example
I advise you to go with:
The easiest way to link the "Model" and "View" of my program would simply be to change the "Model" class to have an ObservableList and not an ArrayList
Maybe use a ReadOnlyListWrapper to expose the ObservableList from the MachineMonitor to the outside world, so that nothing can modify it unduly.
Setup some other structure which encapsulates the view (for example a ControlPanel and ControlPanelSkin) and provide it a reference to the read only observable list of MachineMonitors. The ControlPanelSkin can encapsulate a TableView, a graph or whatever visual knobs and widgets you want to use for the user to monitor the machines.
Using such a structure effectively isolates your view from the model. The model really doesn't know anything about the UI at all and ControlPanelSkin implementation could be changed out to a completely different visual representation or technology without changing the core MachineMonitor system at all.
The above just outlines a general approach, you'll need to tweak it for your specific example.
I disagree that using an ObservableList in your "model" class violates MVC separation. An ObservableList is purely data representation; it is part of the model and not part of the view. I (and others) use JavaFX properties and collections in model representations in all tiers of my applications. Among other things in there, I point out how I use JavaFX properties that are (or can be, at least) bound to JSF. (I should mention that not everyone agrees with the approach of using FX properties on the server side; however I don't really see any way to make the argument that they are somehow part of the view.)
Also, if you do
List<MachineMonitor> myNonObservableList = ... ;
ObservableList<MachineMonitor> myObservableList = FXCollections.observableList(myNonObservableList);
myObservableList.add(new MachineMonitor());
the observable list is backed by the non-observable list, so the change occurs in myNonObservableList too. So you can use this approach if you prefer.

java - Best way to display object properties

Reflection or hashmaps? Suppose you are writting a graphical application where you have objects lying around and users have the posibility of clicking on them. That said, you want to display the clicked object information somehow.
I end up reading Accessible interface from accessibility java package and AccessibleContext class... Before that, I wrote testing code using hash maps for properties instead of class fields. And lastly, I thought in Reflection after reading that JavaBeans use instrospection.
What would you recommend in such applications?
Using reflection and introspection sounds like a better approach than using HashMaps. Instead of using this API directly, I would recommend an abstraction layer like Commons BeanUtils, which will allow you to work with classes adhering to the JavaBean standard in an easy manner.
Here's the User Guide complete with examples.

I want to change the language of a SWT Application at Runtime. How to do that?

I'm developing an application to my software engineering class and one of the requisites is that it has 2 or more languages in the interface. I already implemented that. On the other hand, it is required that the user can change the language on its own will by choosing from a combobox or something like that.
As i'm using AWT and Netbeans, I can't edit the initComponents method of the form, as it is automatically generated. I have the option below in mind, but don't know if they would even work, so I'm asking for help.
-Edit the constructor of my class so that it looks like this:
public JFmyConstructor() {
initComponents(); //auto-generated
myInitMethod();
}
The problem I think i'm going to find is that I need to call the constructor one time after the interface is already running (and thus, all objects instantiated. Is there a workaround for this?
Probably my answer comes a little late (too bad you put wrong title)...
Obviously you do not have to call any constructor in order to switch language at runtime. In Java Desktop applications it is as ease as:
Locale brazilian = new Locale("pt", "BR");
Locale.setDefault(brazilian);
Of course if you want to switch it via JComboBox, you would probably do it a bit different. What I would do, I would actually create Model (Swing promotes MVC Design Pattern) that will hold data (different Locales) and I would set default Locale in correct ActionListener. It is not easy though.
Of course I would rather use native names for Locales. If you have them constructed, you can easily get native name Locale name by simply calling getDisplayName() passing itself as a parameter:
String brazilianNativeName = brazilian.getDisplayName(brazilian);
The result might be unsatisfactory for certain Locales (I believe Brazilian Portuguese is unfortunately one of them), but there is not much you can do about it (unless you use your own string).
To be honest, for just two languages, I would probably use some links instead. You can use simple JLabels to do that, just set correct font properties and color and assign common ActionListener. You can then query which one was actually clicked and create and set Locale appropriately. For homework that should be sufficient.
SWT and NetBeans is a weird combination. If you can do things the "normal" way with SWT and use Eclipse, then there's a powerful set of tools for managing localization, all built right in. See, for example, this introduction.
The best way is to use resource injection for all components (rather than getting i18n strings from a Bundle at panel construction time).
Resource Injection is available in a number of open source libraries or frameworks.
Since you use NetBeans, you should be able to generate an application based on Swing Application Framework (SAF), which already supports Resource Injection.
Otherwise, there are also libraries out there that do just that; simply google for "swing" "resource injection" and you'll find, e.g. Fuse library.
Edit:
You should also take a look at this SO question that deals exactly with the same problem, and which has more detailed answers (including my own).

Java SWT design patterns

What are some good design patterns for creating a form in java?
I have an app that has 6 tabs with a different form in each. How does the typical java programmer go about making these items accessible?
For example as a wpf programmer I might databind all these controls to underlying objects.
What do java programmers like to do?
I don't know what programmers like to do, but you should listen to what MVC patterns tells.
And it tells you that each view should have its controller. Your view has obviously subviews. So the design in this case would obviously be following:
MainView
Label1
Text1
Tab1Subview
Label1
Text1
Tab2Subview
Label1
Text1
MainViewController
Tab1SubviewController
Tab2SubviewController
And controllers will define the binding for each particular view. You can also use one single controller for all subviews and bind it inside. Your main controller could have a link to main root model object e.g. Forms. And particular controller could bind subobjects. As I already said again - you can go with one big controller and bind it all in one place.
This is for what MVC was created.
Tools
If you are looking for SWT graphical designer, then the Window Builder Pro (Eclipse Plugin) - is definitely is the choice (not perfect although, but the better of all available).
Things like EMF is quite complicated. You can start with a mix of Window Builder Pro and coding and as mentioned above JFace Binding API will be an option - but it's not necessary - depend on model you can use either JFace Binding or do it yourself in the code.
For saving simple form all you have to do is write something like save method, e.g.:
person.setName(view.getFullNameTextField().getText());
this is not much worse than using advanced binding features, especially if you don't won't dependance on extra libraries like JFace.
If you are using Eclipse, you can try EMF, an amazing framework helps you to design your model, generate Java code, and provides a pretty cool model editor in minutes.
EMF provides data binding between the UI widget and the model, you can read the generated code to see how it works.

Categories