Releases: sialcasa/mvvmFX
1.7.0
Breaking Changes
- #149: The
mvvmfx-cdimodule now uses CDI in version 2 and is now independend fromWeld. This means you can also use other CDI implementations like Apache OpenWebBeans.
However, this also means that you have explicitly add such a CDI implementation to your dependencies. If you like to use Weld like before you have to add the dependency toweld-se-core.
New Features and Improvements
-
#249: It is now possible to define a custom path to a FXML file for a view and this way override the naming conventions of mvvmFX. For this add the new annotation
@FxmlPath("/path/to/your/fxml")on
your view class. An example can be seen here -
#518: It is now possible to provide multipe resource-bundles when loading a view via
FluentViewLoaderby invoking theFluentViewLoader#resourceBundlemethod multiple times. -
#491: The ModelWrapper now also supports mapping of immutable data classes.
-
#498: If the
fx:controllerattribute in a FXML file points to a ViewModel instead of a View class now an exception with meaningful message is thrown to help finding this misconfiguration. -
#503: All our internal unit-tests are now using JUnit 5. #504 Together with this change we've introduced an equivalent of the old
JfxRunnerthat can be used in JUnit 5 tests to run them in a JavaFX environment with a JavaFX platform thread at hand. -
#131: It is now possible to register customer builder-factories. This can make using custom controls easier in some situations.
-
#481: The
CompositeValidatornow provides an unmodifiable observable list of all it's sub-validators. This can be used to calculate a percentage of valid/invalid sub-validators. -
#332: Prerior to this release you had to implement a method
public void initialize()to make mvvmFX invoke this initializer method after dependency injection is done. This confirms to the JavaFX initialize naming-convention. In addition to this it is now also possible to define any method with any visibility in a ViewModel as an initializer-method by using the new annotation@Initialize. This makes it also possible to have more than one initializer method in a single ViewModel. Existing code with the old naming-convention approach still works.
1.6.0
Breaking Changes
- #454: The validation feature was moved into it's own sub-module. This way it's possible to use the validation classes without importing the whole mvvmFX framework. If you are using the validator you have to add the new dependency to your maven/gradle build script:
<dependency>
<groupId>de.saxsys</groupId>
<artifactId>mvvmfx-validation</artifactId>
<version>1.6.0</version>
</dependency>The API and packages of the classes haven't changed so everything you have to do to get your build file.
- #308: If using a dependency injection framework you can add
@PostConstructto methods to execute setup code after a class was created and has all dependencies injected. However, if you name this method "initialize" in a ViewModel then this conflicts with the initialization logic of the mvvmFX framework. In this case the method will be invoked 2 times. See the wiki for a detailed explanation. In this situation now an exception is thrown. To fix this you have to rename your@PostConstructmethod. This change is potentially a breaking change for some users even though it's unlikely that this combination ever worked properly anyway. Thx to @sideisra for reporting and to @sirwindfield for fixing.
New Features and Improvements
- #381: ViewModels now support a basic lifecycle to react on the event of the view being added to or removed from the Scene. This way you can implement cleanup logic in your ViewModels to prevent possible memory leaks.
See the wiki page for more informations. - #349: Next to the existing CDI and Guice modules for dependency injection there is now a new module for the EasyDI dependency injection library. EasyDI is a small library for small to medium sized projects. While it's not as powerful as CDI or Guice, it has less configuration overhead and can be much faster then the other two in some situations. Thx to @sirwindfield for the implementation.
- #443: It's now possible to add more complex validation rules to the
ObservableRuleBasedValidator. Previously it was only possible to add ObservableBoolean rules with a fixed message. Now it's also possible to add anObservable<ValidationMessage>. This way you can define dynamic messages that are used when the validation fails. See the wiki for a short example. Thx to @gtnarg for the idea. - #423: The ModelWrapper now correctly sets the name attribute of each created JavaFX Property. Thx to @pkantner for the proposal.
- #421: The ModelWrapper now has a method
copyValuesTowhich takes a model instance as argument and copies all current values of the wrapper into the provided model instance. Thx to @pkantner for the proposal. - #345: The
ListTransformationclass has amodelListproperty which is now renamed tosourceList. The new name better reflects what the class is doing by using "source" and "target" as terms. The oldmodelListproperty is still available but is now marked as deprecated and will be removed in a future version. Thx to @tranquility79 for implementation.
Bugfixes
- #442: The
DelegateCommanddidn't provide access to an exception that was thrown by the executed action when the command was executed in synchronous mode. You can now access such exceptions withDelegateCommand.getException()method. Thx to @AKreisel for reporting and to @tranquility79 for fixing. - #399: A
DelegateCommandwasn't able to be restarted properly. Thx to @tfleis for reporting. - #441: It was possible to subscribe to a
NotificationCenterwithnullas subscriber. Later, whenunsubscribeis invoked this was resulting in aNullPointerException. - #435: When a resourceBundle is injected with
@InjectResourceBundleannotation then an exception should be thrown when no resourceBundle was provided when loading the scene. This wasn't the case anymore due to a regression in the code. - #426: Injecting a Scope
Contextwith@InjectContextwasn't working when an existing ViewModel instance was used for loading the scene. Thx to @sideisra for reporting. - #419: The
ListTransformationclass was using an immutable list internally for the model list in some situations. This was resulting inUnsupportedOperationExcepionwhen new model elements are added to the model list, which of cause is a reasonable usage. Now a normal observable ArrayList is used. - #415: With version 1.51. we introduced a regression by changing the implementation hierarchy of the
CompositeValidatorwhich breaks customValidationMessageimplementations. Thx to @gtnarg for reporting.
Documentation and examples
- #447: The Contacts example was using an old version of ControlsFX which isn't supported on newer JDKs like 102 and 112. Thx to @bekwam
- #446: There is a new example app that shows how to implement asynchronous behavior with Java CompletableFuture.
1.5.2
1.5.1
This is a bugfix release.
ModelWrapper
- #404 A
NullPointerExceptionwas thrown whenuseCurrentValuesAsDefaultis invoked when no model instance is set in the ModelWrapper - #402 When a new model was set the default values were overwritten. Thx to @johnp for fixing.
- #393 When the user created a field of Type
StringPropertythat uses another StringProperty as accessor (instead of simple getter and setter), the default value wasn't applied. Thx to @johnp for fixing.
Validation
- #398 In version 1.5.0 we introduced
equalsandhashCodemethods forValidationMessageclass. This change introduces a problem with theCompositeValidatorwhen multipe validators were producingValidationMessageswith equal message text and severity. Now the CompositeValidator handles such cases correctly. Thx to @tfleis for reporting.
Other
- #310
DelegateCommandwasn't executing callbacks for "succeeded" and "failed" when used in synchronous mode.
1.5.0
This version contains many improvements and small features. Additionally we are releasing a first version of our Scopes feature.
New Features
- After a lot of work durring this release cycle we have introduced a first version of our Scopes feature. A Scope is a data context that can be used by multiple components to share common data without tight coupling between each other.
While there are still some open questions and issues with this feature (#383) we have decided to release it so that potential users can try it out and provide feedback. This means the Scopes feature is in BETA state at the moment.
See the wiki for more informations on how to use scopes.
Small Features and Improvements
- #384: The
executableparameter ofDelegateCommandis now of typeObservableValue<Boolean>instead ofObservableBooleanValue. This can simplify the usage in some use cases. - #286: Introduces
WeakNotificationObserver. This can be used as wrapper for theNotificationObserverto prevent memory leaks. This is similar to WeakChangeListener of JavaFX. The usage is described in the wiki. - #369: The
DefaultNotificationCenteris now public and has a public constructor. This can be useful for testing purposes. - #356: The initialization of an existing ViewModel instance was inconstent between
JavaViewandFxmlView. When an existing ViewModel instances was passed to theFluentViewLoaderwhen loading aJavaView, theinitializemethod of the ViewModel instance was invoked by the framework in previous versions. Now this isn't the case anymore. This behaviour is constistent with the existing behaviour ofFxmlViews. For users ofJavaViewthis may be a breaking change because existing logic that depend on this behaviour may not work anymore. - #350: The
FluentViewLoaderwas missing the possibility to provide an existing CodeBehind when loadingJavaViews. This is now fixed.
ModelWrapper
- #376: The order in which the ModelWrapper commits and reloads values is now deterministic. In the past the order wasn't specified but now can be assumed to be deterministic. Thanks to @sideisra.
- #372: The ModelWrapper now has an additional constructor taking an
ObjectPropertyof the wrapped model type. When the value of the property changes the ModelWrapper will reload it's internal values automatically. Thanks to @sideisra. - #366: The ModelWrapper has now the possibility to update the default values for it's fields. This can be done by calling
useCurrentValuesAsDefaultsmethod. Thanks to @sideisra.
Validation
- #364: The
ValidationMessageclass has now a proper implementation ofequalsandhashCodemethods which makes testing of validation logic easier. - #359: The
ValidationMessageclass has now a public constructor to support subclassing.
Bugfixes
- #376 Fixed a potential memory leak in the direct notification mechanism between ViewModel and View due to the fact that the ViewModel instance was used as channel identifier.
1.4.1
This release contains some bugfixes:
- [#335] ViewModels were not injected when Guice AOP interceptors were used. Thx to @archislav for reporting and helping to find the issue.
- [#311] exceptions were silently catched when `DelegateCommand' was used in synchronous mode.
- [#319] the injection behaviour between
JavaViewandFxmlViewwas inconsistent when no generic ViewModel type was defined. In case ofJavaViewnow an exception is thrown to match the behaviour ofFxmlViews.
1.4.0
This release contains mostly improvements and bugfixes:
Improvements
- [#221] The ModelWrapper now supports mapping for (observable) lists. Thx to @lihop for this contribution.
- [#247] JFX-Testrunner is now integrated in mvvmfx-testing-utils. This util is still in beta state and will be further improved in the future.
- [#275] The
CachedViewModelCellFactorynow supports customization of theViewListCells. - [#287] The implementation of the
NotificationCentercan now be replaced with the new MethodNotificationCenterFactory.setNotificationCenter(...). This can make testing easier because you can now use a mock notification center. - [#258] The
GCVerifierhad a dependency to the assertJ library. This dependency was removed. - [#293] The
CachedViewModelCellFactoryhas now a shortcut method for use cases where the cell is an mvvmFX-View. For example:CachedViewModelCellFactory.createFxmlView(MyView.class);creates a cellfactory, that loads anMyViewfor every cel. - [#303] A new check in the loading mechanism was added. When a View tries to inject a ViewModel with
@InjectViewModelwe now check that the type of the ViewModel matches the declared generic type of the View. - [#269] Maven dependencies are now using the maven dependency management feature. Thx to @tomasz for this contribution.
- [#279] For the mvvmfx-cdi module the dependency to
org.jboss.weld.se:weld-sewas replaced withweld-se-coreasweld-seis an uber-jar. This should prevent dependency problems when using other libraries that also have dependencies to weld-se. Thx to @tomasz for this contribution.
Bugfixes
- [#281] The ListTransformation util was firing multiple change events when multiple elements where added. This was leading to problems with
FilteredList. Now only one change event is fired. - [#292] Under some special conditions a new ViewModel instance was created even if an existing instance was provided to the FluentViewLoader.
- [#301] NotificationCenter was throwing a NullPointerException when trying to remove an observer that isn't registered.
Documentation
- [#252] Documentation for the
@InjectViewModelannotation in combination with dependency injection frameworks was added in the wiki. - [#217] All examples are now restructured. The "examples" directory contains 3 big example applications books-example, contacts-example and todomvc-example. Additionally there is a subdirectory "mini-examples" for the smaller examples like the helloworld app.
1.3.1
This is a small release with two fixes for problems introduced with the last version 1.3.0.
- Due to the fix for #240 some users had breaking unit tests because of a "toolkit not initialized" Exception when publish/subscribe of the ViewModel was part of the JUnit test. We are now checking if there is a JavaFX UI thread present or not. If no UI thread is present (f.e. while running JUnit tests), the notifications will be published on the current thread like it was done before. This way we can support easy unit tests and still make sure that at runtime all notifications are published on the UI thread. (#263)
- Additionally we have introduced a
NotificationTestHelperthat can be used to test notifications. The test helper can even be used for use cases where notifications are send from different threads and it will handle the UI thread accordingly. See the new paragraph in the Wiki for more informations: https://github.com/sialcasa/mvvmFX/wiki/NotificationCenter#testing-notifications - There was a problem with the
getHighestMessagemethod of theValidationStatusclass introduced with #194. In some cases inside of ChangeListeners on thevalidPropertyor one of the observable lists of validation messages, thegetHighestMessagewas throwingIndexOutOfBoundExceptions. We have now a new implementation for this method that fixes the problems. (#264)
1.3.0
The biggest feature in this release is the support for validation and an extended support for ResourceBundles.
Validation (BETA) (#194)
Docs: https://github.com/sialcasa/mvvmFX/wiki/Validation
- The user can now use
Validators to define validation logic in the ViewModel. In the View there areValidationVisualizers used to show validation results from the ViewModel in the View. This way the validation logic is separated from UI code and can be tested. - There are 3 validator variants at the moment:
FunctionBasedValidator,ObservableRuleBasedValidatorandCompositeValidator - An implementation of a
ValidationVisualizeris provided that uses the third-party library "ControlsFX" for decoration.
ResourceBundle handling
Docs: https://github.com/sialcasa/mvvmFX/wiki/resource-bundles-i18n
In both cases there is a hierarchy of the bundles so that values from the global resourceBundle are overwritten (if they share the same key) by values from the per-view bundle (the one that is provided to the FluentViewLoader) and these again are overwritten by bundles for fx:included FXML files.
ModelWrapper now has "dirty" and "different" flag (#232)
dirtyPropertyindicates whether a change was done to at least one of the properties of the ModelWrapper instancedifferentPropertyindicates whether the values of the properties of the ModelWrapper are different to the wrapped model instance. In contrast to thedirtyPropertythis flag will switch back tofalsewhen the user changes the property value back to the value of the model object.
Bugfixes
- In contrast to the statements in the JavaDoc a notification published directly from the ViewModel wasn't delivered on the UI thread in any case. (#240)