MVP, JavaFx and components references - java

I've studied all popular GUI patterns - MVP,MVC,MVVM and finally I decided to implement MVP (Supervising Controller). So I have the following OBJECTS(!). Stage<-View<->Model. It's important Stage!=View, it is another object. Between view and model data binding. Besides I have a presenter(controller) which handles all events and works with view and model, so View<-ViewInterface<-Controller->Model.
The problem is now how to get references to labels, textAreas etc in view. Javafx allows to use #FXML annotation to inject these components to controller. However, using MVP I need these components in View, as all logic for view is in View and I don't need them in controller. The only solution I know is:
public class MyView{
private Button button;
public MyView(){
...
button=(Button) root.lookup("#myButton");
}
}
That is to get references by their ID. However I don't like it. Or I do something wrong or I understand something wrong but I think a better solution exist. Please, help me to find it.

JavaFX has been designed to work with the MVC pattern. Hence it is much easier to use MVC than MVP. In MVP Presenter is responsible for formatting the data to be displayed. In JavaFX, it is done automatically by View. Here's a quick overview of JavaFX MVC:
Model - the domain data / data structure that you work with in your application (e.g. Person, Employer, Coursework, etc)
View - the UI definition of the application and its Model. The preferred way of creating a view is via an FXML file, which is essentially the View in JavaFX MVC.
Controller - the bridge between Model and View. The code is typically isolated in XController class (where X is the name of the FXML View). The instance of Controller is automatically injected by FXMLLoader or can be done manually in case you require a custom Controller. The Controller class will have access to UI (View) elements in order to be able to manipulate different properties and also the Model, so that it can perform operations based on the UI (View) input.
To sum up, in JavaFX you don't need to have class View, the View definition should be entirely in the FXML file. All UI elements should be injected with #FXML into your Controller class. If you absolutely have to use MVP, then AWT/Swing or MVP4j - http://www.findbestopensource.com/product/mvp4j might be a better option.
For more detailed explanation please have a look at the official Oracle tutorial for JavaFX: http://docs.oracle.com/javase/8/javafx/get-started-tutorial/jfx-overview.htm
If you require help building UI using FXML: http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html
This tutorial covers basics of MVC in JavaFX and how each component communicates with others: http://code.makery.ch/library/javafx-8-tutorial/part1/

As an Android developer, I always use MVP pattern in my applications. MVC compared to MVP seems so old to me, so when I started working on a new Java app, I felt a little bit lost.
Here there is my solution:
Initial steps
In fxml files create the UI, without specifying a controller, because you don't need one.
Create the Java interfaces (IView, IPresenter and so on..)
Implement the IPresenter interface in the Presenter class, as you would do normally (do http requests, query a DB..)
Now the interesting part:
Adapting your view to MVP pattern
Let's see some code:
Create your GUI (for example a Main GUI) and implement your View interface
public class MainGUI extends Application implements MainContract.View {
public static void main(String... args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws IOException {
//here we will load fxml or create the ui programmatically
}
//method from view interface
#Override
public void onServerResponse(String message) throws IOException {
//update the view
}
Now the last step:
Communicating with the presenter
To do this, we first create an istance of our presenter:
private MainContract.Presenter presenter;
public MainGUI() {
presenter = new MainPresenter(this);
}
this is, of course, the MainContract.View implemented in the MainGUI class
Now we have to get a reference to the view components
private ComboBox<Double> mySimpleList;
#Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("layout_main.fxml"));
Parent root = loader.load();
mySimpleList= (ComboBox<Double>) loader.getNamespace().get("mysimplelist_id");
...
primaryStage.setScene(new Scene(root, -1, -1));
primaryStage.show();
I prefer using fxml files instead of creating the ui by code, but the logic behind is identical.
Set the items
...
mySimpleList.setItems(ValuesFactory.getMyValues());
And the listener
...
mySimpleList.valueProperty().addListener(simpleListListener);
What is simpleListListener?
A simple ChangeListener, where we finally call a presenter method
simpleListListener = (ChangeListener<Double>)
(observable, oldValue, newValue) -> presenter.doTheLogic(newValue);
This is an easy scenario, but in principle this is how we can use MVP Pattern with JavaFX. I also understand that it isn't the definitive solution, so I hope that one day there will be more docs where I can learn more about this argument!
Let me know if I wasn't clear in some part of the code

Related

Dealing with Dependencies when instantiating MVC objects in Java

I know that's not the most amazing title in the world, but bear with me.
I'm developing an application in Java, for part of which I'm using the MVC design pattern.
Above is my understanding of the MVC structure, or at least how I'm choosing to implement it. However I've run into a problem instantiating the objects. Since any given controller requires a reference to it's view pair, and any given view requires a reference to it's controller pair, I'm not sure how to actually create the objects.
I could pass the view into the controller as null and then immediately set it, but not only does this feel like bad coding practice it raised questions about where I actually should be creating the view. Is it something normally delegated to the controller? Any guidance would be greatly appreciated.
You can pass one as a constructor parameter to the other like this:
public class Controller {
private View view;
public Controller() {
this.view = new View(this);
}
}
public class View {
private Controller controller;
public View(Controller controller) {
this.controller = controller;
}
}

View related commands in MVVM application

I was inspired by article Decouple the View and its behavior to create a testable UI and wanna rework my JavaFX application with MVVM pattern.
(source: s-msft.com)
.
Ideally View Model should be View-independent and be testable as usual Java class. Also MVVM uses Command conseption to change View Model from View. So Command implementation is a part of View Model implementation and may be simply tested.
The questions is how Command should be implemented if it's result is a View changing? E.g. in View_1 I have a button after pressing on it a new View (e.g. View_2) should be created and shown. Should such Command be a part of a View and not be testable at all?
I think command could be testable. I'm not sure how exactly are you going to switch views, but AFAIK in JavaFX there is something like a Scene and Stage which is parent for scenes, is that right?
So in your command you pass the Stage as a dependency and on execution you set it a new scene.
And you can easily test it in unit tests - you can mock Stage and check if command passes correct scene to it.
I don't remember exact details of JavaFX but I would implement it like this:
class SwitchSceneCommand {
protected Stage stage;
protected Scene originalScene; // you can keep original scene if you want to have some undo-redo functionality
protected Scene newScene;
public SwitchSceneCommand(Stage stage, Scene originalScene, Scene newScene)
{
this.stage = stage;
this.originalScene = originalScene;
this.newScene = newScene;
}
public void execute()
{
this.stage.setScene(this.newScene);
}
}

java MVC application

i'm creating an application at the moment that i want to reuse the GUI so to make it easy to reuse and change the elements I've been using the MVC design pattern but im having a few issues with it the first issue is how to implement the actual design pattern as different examples implement it in different ways. this is the code i have in my main, does this look ok.
mainView theView = new mainView();
mainModel theModel = new mainModel();
mainController theController = new mainController(theView,theModel);
theView.setVisible(true);
The second problem i have was the example set up was the controller implemented a view in the by using the following code:
controller:
this.theView.addCalculateListener(new CalculateListener());
view:
public void addCalculateListener(ActionListener listenForCalcButton){
calculateButton.addActionListener(listenForCalcButton);
}
this seems to work fine but i have problems implementing listeners in the JMenu as there added within the constructor of the view so my plan was to create the JMenu in an external class where i can put all the menu items as global variables (to clear up code) which will allow me to add the listeners in this manner, is this an OK solution or am i way off.

Thin controllers

I am getting my feet wet with javafx. This is what I am doing.
FXML Views
DI Controllers
Weld-SE Managed Services and Models
Trying to confine UI to FXML
Trying keep the Controllers thin
Problem:
While trying to code the UI, most static UI is confined inside the fxml. But there are scenarios where I find my self adding, removing, showing, hiding elements etc.
I find myself doing this inside the controller as fx lets me configure controller method in the view which it will call on a particular action / event. All this code deals with Dynamic UI building / manipulating and belongs inside the view layer. But, it ends up in controller making the controllers fat.
javafx provides javascript integration. This is one possible way to abstract that view manupulation code away. But this would add not so perfect javascript into the mix.
How would I abstract the code away in java or fxml so that I don't break the Thin Controller Paradigm ?
EDIT
#assylias
Agreed, I have thought about this and this way that java class and fxml together become a reusable widget. But then, how do I wire this into FXML. FXML doesn't understand anything but a controller. Let say I wire this view class into fxml using fx:controller and not name it controller. So I have something like this.
This view class has nothing but view manipulation code. Then I would create another controller class. But then I would expect to somehow fill the form data into this controller. This should only happen when the user has submitted the form. So in a way, I need to tell javafx somehow that UI manipulation request / event is different from actual data manipulation request / event.
Your thoughts, sorry if it was verbose. Tried to articulate it in as few words as I could.
I think the easiest solution to this is to remember that the controller specified in FXML is a view controller. It's purpose is to contain code to modify and update the view, not to contain traditional MVC controller code or business logic.
For example, in a project I'm currently working on, I'm using JavaFX with Akka Actors. The application is written in scala. The JavaFX view controllers contain any code necessary to modify the view. One screen contains a login form. When the user clicks the login button, the view controller simply creates a message containing the username and password, and sends that message to the actor responsible for doing business logic. If that actor determines there is an error then it will send a message back to the view controller, and the view controller can decide what sort of updates need to be made on the screen.
I've found that using akka actors with JavaFX greatly simplifies coding the application for at least two reasons.
Because using an actor system mandates sending messages between actors, there is a natural boundary between presentation code and business code. The messages that are passed back and forth form this natural boundary.
Using actors completely replaces the complexity of working with threads/tasks. It completely eliminates the need to code javafx.concurrent.Task's for long running processes.
How about putting your view manipulation code in Main Class ?
Main Class :
public class SampleJavaFXApp extends Application{
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource(
"SampleUI.fxml"));
Parent root = (Parent) loader.load();
Controller controller = loader.getController();
viewManipulationLogic(controller);
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
// view manipulation logic
private void viewManipulationLogic(Controller controller) {
controller.getBlueButton().setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
System.out.println(" I am just about button!");
}
});
}
Controller :
public class Controller implements Initializable {
#FXML
private Button blueButton;
public Button getBlueButton() {
return blueButton;
}
#Override
public void initialize(URL arg0, ResourceBundle arg1) {
//real data manipulation
}
}
cons : You need getters for all Nodes u want to manipulate , in controller class.

Is there a recommended way to use the Observer pattern in MVP using GWT?

I am thinking about implementing a user interface according to the MVP pattern using GWT, but have doubts about how to proceed.
These are (some of) my goals:
the presenter knows nothing about the UI technology (i.e. uses nothing from com.google.*)
the view knows nothing about the presenter (not sure yet if I'd like it to be model-agnostic, yet)
the model knows nothing of the view or the presenter (...obviously)
I would place an interface between the view and the presenter and use the Observer pattern to decouple the two: the view generates events and the presenter gets notified.
What confuses me is that java.util.Observer and java.util.Observable are not supported in GWT. This suggests that what I'm doing is not the recommended way to do it, as far as GWT is concerned, which leads me to my questions: what is the recommended way to implement MVP using GWT, specifically with the above goals in mind? How would you do it?
Program Structure
This is how I did it. The Eventbus lets presenters (extending the abstract class Subscriber) subscribe to events belonging to different modules in my app. Each module corresponds to a component in my system, and each module has an event type, a presenter, a handler, a view and a model.
A presenter subscribing to all the events of type CONSOLE will receive all the events triggered from that module. For a more fine-grained approach you can always let presenters subscribe to specific events, such as NewLineAddedEvent or something like that, but for me I found that dealing with it on a module level was good enough.
If you want you could make the call to the presenter's rescue methods asynchronous, but so far I've found little need to do so myself. I suppose it depends on what your exact needs are. This is my EventBus:
public class EventBus implements EventHandler
{
private final static EventBus INSTANCE = new EventBus();
private HashMap<Module, ArrayList<Subscriber>> subscribers;
private EventBus()
{
subscribers = new HashMap<Module, ArrayList<Subscriber>>();
}
public static EventBus get() { return INSTANCE; }
public void fire(ScEvent event)
{
if (subscribers.containsKey(event.getKey()))
for (Subscriber s : subscribers.get(event.getKey()))
s.rescue(event);
}
public void subscribe(Subscriber subscriber, Module[] keys)
{
for (Module m : keys)
subscribe(subscriber, m);
}
public void subscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).add(subscriber);
else
{
ArrayList<Subscriber> subs = new ArrayList<Subscriber>();
subs.add(subscriber);
subscribers.put(key, subs);
}
}
public void unsubscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).remove(subscriber);
}
}
Handlers are attached to components, and are responsible for transforming native GWT events into events specialised for my system. The handler below deals with ClickEvents simply by wrapping them in a customised event and firing them on the EventBus for the subscribers to deal with. In some cases it makes sense for the handlers to perform extra checks before firing the event, or sometimes even before deciding weather or not to send the event. The action in the handler is given when the handler is added to the graphical component.
public class AppHandler extends ScHandler
{
public AppHandler(Action action) { super(action); }
#Override
public void onClick(ClickEvent event)
{
EventBus.get().fire(new AppEvent(action));
}
Action is an enumeration expressing possible ways of data manipulation in my system. Each event is initialised with an Action. The action is used by presenters to determine how to update their view. An event with the action ADD might make a presenter add a new button to a menu, or a new row to a grid.
public enum Action
{
ADD,
REMOVE,
OPEN,
CLOSE,
SAVE,
DISPLAY,
UPDATE
}
The event that's get fired by the handler looks a bit like this. Notice how the event defines an interface for it's consumers, which will assure that you don't forget to implement the correct rescue methods.
public class AppEvent extends ScEvent {
public interface AppEventConsumer
{
void rescue(AppEvent e);
}
private static final Module KEY = Module.APP;
private Action action;
public AppEvent(Action action) { this.action = action; }
The presenter subscribes to events belonging to diffrent modules, and then rescues them when they're fired. I also let each presenter define an interface for it's view, which means that the presenter won't ever have to know anything about the actual graphcal components.
public class AppPresenter extends Subscriber implements AppEventConsumer,
ConsoleEventConsumer
{
public interface Display
{
public void openDrawer(String text);
public void closeDrawer();
}
private Display display;
public AppPresenter(Display display)
{
this.display = display;
EventBus.get().subscribe(this, new Module[]{Module.APP, Module.CONSOLE});
}
#Override
public void rescue(ScEvent e)
{
if (e instanceof AppEvent)
rescue((AppEvent) e);
else if (e instanceof ConsoleEvent)
rescue((ConsoleEvent) e);
}
}
Each view is given an instance of a HandlerFactory that is responsible for creating the correct type of handler for each view. Each factory is instantiated with a Module, that it uses to create handlers of the correct type.
public ScHandler create(Action action)
{
switch (module)
{
case CONSOLE :
return new ConsoleHandler(action);
The view is now free to add handlers of different kind to it's components without having to know about the exact implementation details. In this example, all the view needs to know is that the addButton button should be linked to some behaviour corresponding to the action ADD. What this behaviour is will be decided by the presenters that catch the event.
public class AppView implements Display
public AppView(HandlerFactory factory)
{
ToolStripButton addButton = new ToolStripButton();
addButton.addClickHandler(factory.create(Action.ADD));
/* More interfacy stuff */
}
public void openDrawer(String text) { /*Some implementation*/ }
public void closeDrawer() { /*Some implementation*/ }
Example
Consider a simplified Eclipse where you have a class hierarchy to the left, a text area for code on the right, and a menu bar on top. These three would be three different views with three different presenters and therefore they'd make up three different modules. Now, it's entirely possible that the text area will need to change in accordance to changes in the class hierarchy, and therefore it makes sense for the text area presenter to subscribe not only to events being fired from within the text area, but also to events being fired from the class hierarchy. I can imagine something like this (for each module there will be a set of classes - one handler, one event type, one presenter, one model and one view):
public enum Module
{
MENU,
TEXT_AREA,
CLASS_HIERARCHY
}
Now consider we want our views to update properly upon deletion of a class file from the hierarchy view. This should result in the following changes to the gui:
The class file should be removed from the class hierarchy
If the class file is opened, and therefore visible in the text area, it should be closed.
Two presenters, the one controlling the tree view and the one controlling the text view, would both subscribe to events fired from the CLASS_HIERARCHY module. If the action of the event is REMOVE, both preseneters could take the appropriate action, as described above. The presenter controlling the hierarchy would presumably also send a message to the server, making sure that the deleted file was actually deleted. This set-up allows modules to react to events in other modules simply by listening to events fired from the event bus. There is very little coupling going on, and swapping out views, presenters or handlers is completely painless.
I achieved something on these lines for our project. I wanted a event-driven mechanism (think of PropertyChangeSupport and PropertyChangeListener of standard jdk lib) which were missing. I believe there is an extension module and decided to go ahead with my own. You can google it for propertychangesupport gwt and use it or go with my approach.
My approach involved logic centred around MessageHandler and GWTEvent. These serve the same purpose as that of PropertyChangeListener and PropertyChangeEvent respectively. I had to customize them for reasons explained later. My design involved a MessageExchange, MessageSender and MessageListener. The exchange acts as a broadcast service dispatching all events to all listeners. Each sender fires events that are listened by the Exchange and the exchange the fires the events again. Each listener listens to the exchange and can decide for themselves (to process or not to process) based on the event.
Unfortunately MessageHandlers in GWT suffer from a problem: "While a event is being consumed, no new handlers can be hooked". Reason given in the GWT form: The backing iterator holding the handlers cannot be concurrently modified by another thread. I had to rewrite custom implementation of the GWT classes. That is the basic idea.
I would've posted the code, but I am on my way to airport right now, will try to post the code as soon as I can make time.
Edit1:
Not yet able to get the actual code, got hold of some power-point slides I was working on for design documentation and created a blog entry.
Posting a link to my blog article: GXT-GWT App
Edit2:
Finally some code soup.
Posting 1
Posting 2
Posting 3
have a look at: http://www.gwtproject.org/javadoc/latest/com/google/gwt/event/shared/EventBus.html
(which outdates http://www.gwtproject.org/javadoc/latest/com/google/web/bindery/event/shared/EventBus.html)
It should run fine with GWT as I'll try right now myself.

Categories

Resources