sialcasa / mvvmfx Goto Github PK
View Code? Open in Web Editor NEWan Application Framework for implementing the MVVM Pattern with JavaFX
License: Apache License 2.0
an Application Framework for implementing the MVVM Pattern with JavaFX
License: Apache License 2.0
Usage of mvvmFX without DI
There are some licence headers missing in the files
At the moment the naming conventions say that the filename of an fxml file has to be the same (case insensitive) as the View class name.
When my View class is named "MainView" the fxml file has to be named "mainView.fxml" (or "mainview.fxml"...).
In my opinion at the level of FXML files the string "View" in the filename is redundant. I would name the file only "main.fxml".
On the other hand, at the level of java classes it makes sense to name the "code-behind" class "MainView.java". This way it`s easier to tell which part of the mvvm pattern the class is related to.
But at the moment this naming combination isn't possible with mvvmfx.
The question is: Should be extend the naming convention so that the user can name the fxml file "main.fxml" and the code-behind "MainView.java"? Or should we stay at the current naming convention?
At the moment there is a mechanism to detect the generic class type in the View class. This mechanism should be extracted to its own util class to be reusable.
Additionally there should be a test that verifies the behaviour of this component.
There is a fixed dependency towards JavaFX 2.2 artifacts in
(http://search.maven.org/#artifactdetails%7Cde.saxsys%7CmvvmFX%7C0.1.2%7Cjar).
<dependency>
<groupId>javafx</groupId>
<artifactId>javafx</artifactId>
<scope>system</scope>
<version>2.2</version>
<systemPath>${java.home}/lib/jfxrt.jar</systemPath>
</dependency>
Better put it into a profile?
Sematic Version Scheme
By default it's assumed that views are created with FXML. This is ok and FXML should be used in most cases.
But in some special cases it's necessary to create Views with Java Code or propably a user doesn't like FXML.
MvvmFX should support this type of Views.
At the moment in the View class you have to use getViewModel()
to get the view model.
It would be better to be able to inject the ViewModel with @Inject
.
public class PersonLoginView extends View<PersonLoginViewModel>{
@Inject
private ViewModel viewModel;
...
}
This way the testablility is improved because you can inject a mock ViewModel in your test View.
The DI-Framework has to find out the generic type of View to inject the correct instance. I don't know wether this is possible in CDI but we could try to find it out.
Fix Raw Type warnings in the Framework
(Integration)-test that all features that are influenced by the dependency injection frameworks are working both with CDI and guice. This would be cool because this way we wouldn't need to manually execute the guice and cdi examples to verify that DI still works.
Errors that are likely to be found with this sort of testing are:
FXMLLoaderWrapper / Viewloader does need new function
public ViewTuple<? extends ViewModel> load(URL location,
ResourceBundle resourceBundle, Node root);
public ViewTuple<? extends ViewModel> load(URL location, Node root);
To call the setRoot Method in Line 64 of FXMLLoaderWrapper.
in the moment you have to register listeners by yours self, by doing
aProperty().addListener(listener);
//and then you had to use the cleaner like this:
listenerCleaner.put(aProperty,listener);
This could be improved by giving a method which registers the listener for you
Provide the possibility to display MVVM-Views in a ListView
We need to find a better way of dependency injection. At the moment we have maven dependencies to both CDI/Weld and Guice frameworks.
We need to check whether it is possible to split and separate the depenencies so that the user can choose the DI framework and doesn't need the dependencies for the other framework. Probably this can be done with different Maven modules.
If this doesn't work we probably need to use and support only one of the DI frameworks. In this case we need to find out which framework is doing the best job for the use cases mvvmfx is designed for.
private void createListEvents() {
// TODO Remove Listener from itemList anywhen - prevent memory leak
itemListProperty().addListener(new ListChangeListener() {
@OverRide
public void onChanged(
javafx.collections.ListChangeListener.Change<? extends ListType> listEvent) {
stringList.clear();
for (ListType item : listEvent.getList()) {
stringList.add(ItemList.this.stringConverter.toString(item));
}
}
});
}
Should not reset the list by clear() , it should do a diff instead!
Another task wich we often had to solve was to intantiate the model of a view tuple just after the tuple was created, especially in the case we had to instantiate it at runtime, f.e. to dynamically assemble composite views. See the following method, which for example could be called in response to a ui request done by the user.
private void openWindow(String userId) { Stage stage = new Stage(); final ViewTuple tuple = viewLoader .loadViewTuple(MainContainerView.class); // lazy init / set model property or model instance tuple.getCodeBehind().getViewModel().setModel(someProperty()); // open a new stage final Parent control = tuple.getView(); final Scene scene = new Scene(control); stage.setScene(scene); stage.show(); }
This issue is about complementing the ViewModel interface with an optional method to override as the following (and so turn into an abstract class), just to make code written with the help of MvvmFX more readable.
public void setModel(Object... model);
Maybe we could also use generics, but this could be over engineered somehow.
Datacontext into ViewModel
integrate from ETEO
In the moment we just access the load function of the FXMLLoader, so we hide the funcitonality of calling the FXMLLoader.load(url,resourcebundle) function
Project should have 100% Test coverage
If the application is running with CDI/Weld, there should be used an implementation of the notification center, which uses the CDI Event mechanism
When the application is packaged as jar the Loader has issues
At the moment the SizeBindings helper is build of overloaded static methods. Because of this some combinations of types for "from" and "to" aren't possible as it wouldn't be clear for the compiler what method should be used.
This implementation style also leads to some ugly code like if-else statements that check for instanceof
.
Maybe we could simplify this class by using the builder pattern.
Instead of:
Pane source = new Pane();
ScrollPane target = new ScrollPane();
SizeBindings.bindSize(source,target);
we could write something like:
SizeBindings.from(source).to(target);
When using Java 8 in both CDI and Guice example there is an exception when clicking on the login-button in the example view. When using Java 7 everything works as expected.
The exception is:
2523 [JavaFX Application Thread] ERROR de.saxsys.jfx.mvvm.viewloader.ViewLoader - Error loading FXML : javafx.fxml.LoadException: Root hasn't been set. Use method setRoot() before load.
If the controller (code-behind) couldn't be created automatically by the FXML Loader (because the user forgot to set the controller class), the framework should create the needed controller by it self with a LOG.warn
Create Guice and Weld Maven Artifacts to provide DI out of the box
This is dangerous, because there can occure runtime errors, if the user does not include the dependency manually. In addition we should remove all javafx annotations from the guice artifact.
Maybe our mvvmfx-cdi module can be build upon the new cathive/fx-cdi project. This could lead to an API that is more similar to our guice module as it is also based on the fx-guice project from the same author.
At the first glance fx-cdi looks great and we should evaluate it.
The problem with our current cdi based Application class is that it doesn't subclass JavaFX's Application class. Maybe this is uncomfortable for some users and there are features missing for this reason. The fx-cdi Application class looks better when it comes to this issue.
The visibility of internal classes has do be minimized
TODO:
We should review the package structure and perform needed refactorings to build a good API. This is a necessary step on the way to a stable API for the framework.
The listener cleaner holds a reference on the listener and the property. This could be a possible memory leak, if the cleaner was not cleaned.
In the moment there exists following memory leaks:
Example for Views in Lists
If there is an Application which does not follow the DI pattern, you can't easily use mvvmFX in the project.
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
When running JDK8 the complex example (both started with cdi and guice) aren't working correctly anymore.
When you "login" a person from the list the welcome message apears but you can't hide it anymore. It seems that the "hide" button doesn't gets the click event or something.
There should be an archetype for mvvmFX projects based on the hello world example.
With respect to our practical experience with the framework we often had to solve the problem to form composite views. Regarding the parallelism constraint between view and view model given by mvvmfx we often had to manually propagate the sub views and view models to its super views. The request described here asks for the framework to support composite views with parallel view models. I will edit this issue and give a code example of how it was done and how it could be done later, if you commit this issue request.
Documentation from readme to wiki
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.