Skip to content

Commit 4e4fc6e

Browse files
author
nicolaiparlog
committed
Merge branch 'feature/nesting' into develop
2 parents fef172b + d5cbd1b commit 4e4fc6e

File tree

100 files changed

+7738
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+7738
-7
lines changed

.classpath

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
<classpath>
33
<classpathentry kind="src" path="src"/>
44
<classpathentry kind="src" path="test"/>
5+
<classpathentry kind="src" path="demo"/>
56
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
67
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
8+
<classpathentry kind="lib" path="lib/mockito-all-1.9.5.jar" sourcepath="lib/mockito-all-1.9.5.jar"/>
79
<classpathentry kind="output" path="bin"/>
810
</classpath>

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
.mtj.tmp/
55

66
# Package Files #
7-
*.jar
87
*.war
98
*.ear
109

.project

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<projectDescription>
3-
<name>CodeFX</name>
3+
<name>LibFX</name>
44
<comment></comment>
55
<projects>
66
</projects>

.settings/org.eclipse.jdt.core.prefs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_
4545
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
4646
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=enabled
4747
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
48-
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default
48+
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
4949
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=warning
5050
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
5151
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
@@ -156,7 +156,7 @@ org.eclipse.jdt.core.formatter.comment.format_header=true
156156
org.eclipse.jdt.core.formatter.comment.format_html=true
157157
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
158158
org.eclipse.jdt.core.formatter.comment.format_line_comments=false
159-
org.eclipse.jdt.core.formatter.comment.format_source_code=true
159+
org.eclipse.jdt.core.formatter.comment.format_source_code=false
160160
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
161161
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
162162
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert

.settings/org.eclipse.jdt.ui.prefs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ cleanup.convert_to_enhanced_for_loop=false
1616
cleanup.correct_indentation=true
1717
cleanup.format_source_code=true
1818
cleanup.format_source_code_changes_only=false
19+
cleanup.insert_inferred_type_arguments=false
1920
cleanup.make_local_variable_final=true
2021
cleanup.make_parameters_final=false
2122
cleanup.make_private_fields_final=true
@@ -30,6 +31,7 @@ cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=tru
3031
cleanup.qualify_static_member_accesses_with_declaring_class=true
3132
cleanup.qualify_static_method_accesses_with_declaring_class=false
3233
cleanup.remove_private_constructors=true
34+
cleanup.remove_redundant_type_arguments=true
3335
cleanup.remove_trailing_whitespaces=true
3436
cleanup.remove_trailing_whitespaces_all=true
3537
cleanup.remove_trailing_whitespaces_ignore_empty=false
@@ -52,7 +54,8 @@ cleanup.use_this_for_non_static_field_access=false
5254
cleanup.use_this_for_non_static_field_access_only_if_necessary=true
5355
cleanup.use_this_for_non_static_method_access=false
5456
cleanup.use_this_for_non_static_method_access_only_if_necessary=true
55-
cleanup_profile=_nipa
57+
cleanup.use_type_arguments=false
58+
cleanup_profile=_'nipa'
5659
cleanup_settings_version=2
5760
eclipse.preferences.version=1
5861
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
@@ -78,6 +81,7 @@ sp_cleanup.convert_to_enhanced_for_loop=false
7881
sp_cleanup.correct_indentation=true
7982
sp_cleanup.format_source_code=true
8083
sp_cleanup.format_source_code_changes_only=false
84+
sp_cleanup.insert_inferred_type_arguments=false
8185
sp_cleanup.make_local_variable_final=true
8286
sp_cleanup.make_parameters_final=false
8387
sp_cleanup.make_private_fields_final=true
@@ -93,6 +97,7 @@ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=
9397
sp_cleanup.qualify_static_member_accesses_with_declaring_class=true
9498
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
9599
sp_cleanup.remove_private_constructors=true
100+
sp_cleanup.remove_redundant_type_arguments=false
96101
sp_cleanup.remove_trailing_whitespaces=true
97102
sp_cleanup.remove_trailing_whitespaces_all=true
98103
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
@@ -115,3 +120,4 @@ sp_cleanup.use_this_for_non_static_field_access=false
115120
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
116121
sp_cleanup.use_this_for_non_static_method_access=false
117122
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
123+
sp_cleanup.use_type_arguments=false

README.md

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,53 @@
1-
codefx
2-
======
1+
# LibFX - Nestings
2+
3+
This feature branch revolves around JavaFX properties. The core API provides awesome capabilities but one thing I frequently need is missing: the possibility to interact with properties which are hidden in a more complex object hierarchy.
4+
5+
Below you will find an example of the problem and its solution with some lines of code from **LibFX**. But before we come to that I wanna shortly present this feature's idea.
6+
7+
## Idea
8+
9+
This branch develops a simple and fluent API to create nestings, where a `Nesting` represents a hierarchy like `Employee -> Address -> ZIP code`. The nesting would collapse the hierarchy to the innermost property (in this example `zipProperty`) and update itself whenever the employee or address instances change.
10+
11+
A nesting can than be used in several ways:
12+
* You can build a property which always holds the innermost value.
13+
* You can attach a change listener which is carried along as the innermost property changes.
14+
* You can create bindings which are not only updated when the innermost property's value changes but also when the property itself is replaced.
15+
16+
These further steps can be made with the same fluent API without breaking one's stride. You can find an example below and more in the classes in the folder `demo/org/codefx/libfx/nesting` (look for methods starting with "demo").
17+
18+
## Example
19+
20+
Let's see an example...
21+
22+
### The Situation
23+
24+
Say you have an object of type `Employee` and you're creating an `EmployeeEditor` for editing a single employee at a time. You will most likely have a model for your UI which has something like a `currentEmployeeProperty`.
25+
Now you might want to bind some properties of the controls you're using for your editor to the current employee's properties. For example you might have a slider and want to bind it to the employee's `salaryProperty`.
26+
27+
### The Problem
28+
29+
Up to now that's all straight forward. But what happens when the current employee is replaced by another? Of course you want your editor to be updated.
30+
31+
### The "Solutions"
32+
33+
You could use `Bindings.select` but it has some downsides. For one thing, it uses strings to identify the nested properties, which breaks down quickly under refactoring. Unfortunately you won't even get an exception when trying to access properties which aren't there anymore - your binding will just forever contain null. Another downside is the return type. It's just an `ObjectBinding` (or `DoubleBinding` or ...) which does not suffice in all use cases.
34+
35+
Another way is to explicitly listen to changes of the model's `currentEmployeeProperty` and update the binding accordingly. That's rather tedious and leads to a lot of the same code all over the place. And it gets even worse, when you're nesting deeper, e.g. binding to the current employee's address' ZIP code.
36+
37+
### The Solution
38+
39+
Use **LibFX**! :)
40+
41+
``` Java
42+
Nestings.on(currentEmployeeProperty)
43+
.nestDouble(employee -> employee.salaryProperty())
44+
.bindBidirectional(slider.valueProperty());
45+
```
46+
47+
``` Java
48+
Nestings.on(currentEmployeeProperty)
49+
.nest(employee -> employee.addressProperty())
50+
.nest(address -> address.zipProperty())
51+
.addChangeListener(myListener);
52+
```
53+
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package org.codefx.libfx.nesting;
2+
3+
import javafx.beans.property.DoubleProperty;
4+
import javafx.beans.property.ObjectProperty;
5+
import javafx.beans.property.Property;
6+
import javafx.beans.property.SimpleDoubleProperty;
7+
import javafx.beans.property.SimpleObjectProperty;
8+
import javafx.beans.property.SimpleStringProperty;
9+
import javafx.beans.property.StringProperty;
10+
11+
/**
12+
* A simple demo class which represents an employee.
13+
*/
14+
class Employee {
15+
16+
/**
17+
* The salary.
18+
*/
19+
private final DoubleProperty salary;
20+
21+
/**
22+
* The address.
23+
*/
24+
private final ObjectProperty<Address> address;
25+
26+
/**
27+
* Creates a new employee with the specified salary.
28+
*
29+
* @param initialSalary
30+
* the employee's initial salary
31+
* @param streetName
32+
* the name of the street the employee lives in
33+
*/
34+
public Employee(double initialSalary, String streetName) {
35+
this.salary = new SimpleDoubleProperty(this, "salary", initialSalary);
36+
this.address = new SimpleObjectProperty<>(this, "address", new Address(streetName));
37+
}
38+
39+
/**
40+
* The salary.
41+
*
42+
* @return the salary as a property
43+
*/
44+
public DoubleProperty salaryProperty() {
45+
return salary;
46+
}
47+
48+
/**
49+
* The address.
50+
*
51+
* @return the address as a property
52+
*/
53+
public Property<Address> addressProperty() {
54+
return address;
55+
}
56+
57+
// #region INNER CLASSES
58+
59+
/**
60+
* A simple demo class which represents an employee's address.
61+
*/
62+
public static class Address {
63+
64+
/**
65+
* The street name.
66+
*/
67+
private final StringProperty streetName;
68+
69+
/**
70+
* Creates a new address with the specified street name.
71+
*
72+
* @param streetName
73+
* the name of the street
74+
*/
75+
public Address(String streetName) {
76+
this.streetName = new SimpleStringProperty(this, "streetName", streetName);
77+
}
78+
79+
/**
80+
* The street name.
81+
*
82+
* @return the street name as a property
83+
*/
84+
public StringProperty streetNameProperty() {
85+
return streetName;
86+
}
87+
88+
}
89+
90+
//#end PRIVATE CLASSES
91+
92+
}

0 commit comments

Comments
 (0)