B
- the bean typepublic class BeanPathAdapter<B>
extends java.lang.Object
Property
components. It allows a
.
separated field path to be traversed on a bean until
the final field name is found (last entry in the .
separated field path). Each field will have a corresponding Property
that is automatically generated and reused in the binding process. Each
Property
is bean-aware and will dynamically update it's values and
bindings as different beans are set on the adapter. Bean's set on the adapter
do not need to instantiate all the sub-beans in the path(s) provided as long
as they contain a no-argument constructor they will be instantiated as
path(s) are traversed.
// Assuming "age" is a double field in person we can bind it to a // Slider#valueProperty() of type double, but we can also bind it // to a TextField#valueProperty() of type String. Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); Slider sl = new Slider(); TextField tf = new TextField(); personPA.bindBidirectional("age", sl.valueProperty()); personPA.bindBidirectional("age", tf.valueProperty());
// Binding a bean (Person) field called "address" that contains another // bean (Address) that also contains a field called "location" with a // bean (Location) field of "state" (the chain can be virtually endless // with all beans being instantiated along the way when null). Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); TextField tf = new TextField(); personPA.bindBidirectional("address.location.state", tf.valueProperty());
// Assuming "address" is an "Address" field in a "Person" class we can bind it // to a ComboBox#valueProperty() of the same type. The "Address" class should // override the "toString()" method in order to show a meaningful selection // value in the example ComboBox. Address a1 = new Address(); Address a2 = new Address(); a1.setStreet("1st Street"); a2.setStreet("2nd Street"); ComboBox<Address> cb = new ComboBox<>(); cb.getItems().addAll(a1, a2); Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); personPA.bindBidirectional("address", cb.valueProperty(), Address.class);
// Assuming "allLanguages" is a collection/map field in person we can // bind it to a JavaFX observable collection/map Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); ListView<String> lv = new ListView<>(); personPA.bindContentBidirectional("allLanguages", null, String.class, lv.getItems(), String.class, null, null);
// Assuming "languages" is a collection/map field in person we can // bind it to a JavaFX observable collection/map selections Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); ListView<String> lv = new ListView<>(); personPA.bindContentBidirectional("languages", null, String.class, lv .getSelectionModel().getSelectedItems(), String.class, lv .getSelectionModel(), null);
// Assuming "languages" and "allLanguages" are a collection/map // fields in person we can bind "languages" to selections made from // the items in "allLanguages" to a JavaFX observable collection/map // selection Person person = new Person(); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); ListView<String> lv = new ListView<>(); personPA.bindContentBidirectional("languages", null, String.class, lv .getSelectionModel().getSelectedItems(), String.class, lv .getSelectionModel(), "allLanguages");
// Assuming "hobbies" and "allHobbies" are a collection/map // fields in person and each element within them contain an // instance of Hobby that has it's own field called "name" // we can bind "allHobbies" and "hobbies" to the Hobby "name"s // for each Hobby in the items/selections (respectively) to/from // a ListView wich will only contain the String name of each Hobby // as it's items and selections Person person = new Person(); BeanPathAdapterpersonPA = new BeanPathAdapter<>(person); ListView lv = new ListView<>(); // bind items personPA.bindContentBidirectional("allHobbies", "name", Hobby.class, lv.getItems(), String.class, null, null); // bind selections that reference the same instances within the items personPA.bindContentBidirectional("languages", "name", Hobby.class, lv.getSelectionModel().getSelectedItems(), String.class, lv.getSelectionModel(), "allHobbiess");
Person person = new Person(); Hobby hobby1 = new Hobby(); hobby1.setName("Hobby 1"); Hobby hobby2 = new Hobby(); hobby2.setName("Hobby 2"); person.setAllHobbies(new LinkedHashSet<Hobby>()); person.getAllHobbies().add(hobby1); person.getAllHobbies().add(hobby2); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); ListView<String> lv = new ListView<>(); personPA.bindContentBidirectional("allHobbies", "name", Hobby.class, lv.getItems(), String.class, null, null); ListView<String> lv2 = new ListView<>(); personPA.bindContentBidirectional("allHobbies", "name", Hobby.class, lv2.getItems(), String.class, null, null);
// When the bean collection/map field is empty/null and it is // bound to a non-empty observable collection/map, the values // of the observable are used to instantiate each item bean // and set the item value (Hobby#setName in this case) Person person = new Person(); final ObservableList<String> oc = FXCollections.observableArrayList("Hobby 1", "Hobby 2", "Hobby 3"); BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); ListView<String> lv = new ListView<>(oc); personPA.bindContentBidirectional("allHobbies", "name", Hobby.class, lv.getItems(), String.class, null, null); ListView<String> lv2 = new ListView<>(); // <-- notice that oc is not passed personPA.bindContentBidirectional("allHobbies", "name", Hobby.class, lv2.getItems(), String.class, null, null);
// Assuming "age" is a double field in person... final Person person1 = new Person(); person1.setAge(1D); final Person person2 = new Person(); person2.setAge(2D); final BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person1); TextField tf = new TextField(); personPA.bindBidirectional("age", tf.valueProperty()); Button btn = new Button("Toggle People"); btn.setOnMouseClicked(new EventHandler<MouseEvent>() { public void handle(MouseEvent event) { // all bindings will show relevant person data and changes made // to the bound controls will be reflected in the bean that is // set at the time of the change personPA.setBean(personPA.getBean() == person1 ? person2 : person1); } });
Date
/Calendar
binding:
// Assuming "dob" is a java.util.Date or java.util.Calendar field // in person it can be bound to a java.util.Date or // java.util.Calendar JavaFX control property. Example uses a // jfxtras.labs.scene.control.CalendarPicker final Person person = new Person(); final BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); CalendarPicker calendarPicker = new CalendarPicker(); personPA.bindBidirectional("dob", calendarPicker.calendarProperty(), Calendar.class);
TableView
binding:
// Assuming "name"/"description" are a java.lang.String fields in Hobby // and "hobbies" is a List/Set/Map in Person final Person person = new Person(); final BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); TableView<Hobby> table = new TableView<>(); TableColumn<Hobby, String> nameCol = new TableColumn<>("Hobby Name"); nameCol.setMinWidth(100); nameCol.setCellValueFactory(new PropertyValueFactory<Hobby, String>("name")); TableColumn<Hobby, String> descCol = new TableColumn<>("Hobby Desc"); descCol.setMinWidth(100); descCol.setCellValueFactory(new PropertyValueFactory<Hobby, String>( "description")); table.getColumns().addAll(nameCol, descCol); personPA.bindContentBidirectional("hobbies", null, String.class, table.getItems(), Hobby.class, null, null);
final BeanPathAdapter<Person> personPA = new BeanPathAdapter<>(person); // use the following to eliminate unwanted notifications // personPA.removeFieldPathValueTypes(FieldPathValueType.BEAN_CHANGE, ...) personPA.fieldPathValueProperty().addListener( new ChangeListener<FieldPathValue>() { @Override public void changed( final ObservableValue<? extends FieldPathValue> observable, final FieldPathValue oldValue, final FieldPathValue newValue) { System.out.println("Value changed from: " + oldValue + " to: " + newValue); } });
bindBidirectional(String, Property)
,
bindContentBidirectional(String, String, Class, ObservableList, Class,
SelectionModel, String)
,
bindContentBidirectional(String, String, Class, ObservableSet, Class,
SelectionModel, String)
,
bindContentBidirectional(String, String, Class, ObservableMap, Class,
SelectionModel, String)
Type | Property and Description |
---|---|
javafx.beans.property.ObjectProperty<java.text.DateFormat> |
dateFormat |
javafx.beans.property.ReadOnlyObjectProperty<BeanPathAdapter.FieldPathValue> |
fieldPathValue |
Modifier and Type | Class and Description |
---|---|
protected static class |
BeanPathAdapter.FieldBean<PT,BT>
A POJO bean extension that allows binding based upon a
.
separated field path that will be traversed on a bean until the
final field name is found. |
static class |
BeanPathAdapter.FieldBeanOperation
BeanPathAdapter.FieldBean operations |
protected static class |
BeanPathAdapter.FieldHandle<T,F>
Field handle to
BeanPathAdapter.FieldHandle.getAccessor() and
BeanPathAdapter.FieldHandle.getSetter() for a given
BeanPathAdapter.FieldHandle.getTarget() . |
static class |
BeanPathAdapter.FieldPathValue
|
static class |
BeanPathAdapter.FieldPathValueType
BeanPathAdapter.FieldPathValue types used for FieldPathValueProperty
changes |
static class |
BeanPathAdapter.FieldProperty<BT,T,PT>
A
Property extension that uses a bean's getter/setter to define
the Property 's value. |
protected static class |
BeanPathAdapter.FieldStringConverter<T>
Coercible
StringConverter that handles conversions between
strings and a target class when used in the binding process
Bindings.bindBidirectional(Property, Property, StringConverter) |
Modifier and Type | Field and Description |
---|---|
static char |
COLLECTION_ITEM_PATH_SEPARATOR |
static char |
PATH_SEPARATOR |
static java.text.DateFormat |
SDF |
Constructor and Description |
---|
BeanPathAdapter(B bean)
Constructor
|
Modifier and Type | Method and Description |
---|---|
void |
addFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
Adds
BeanPathAdapter.FieldPathValueType (s) BeanPathAdapter.FieldPathValueType (s) that
#notifyProperty() will use |
void |
bindBidirectional(java.lang.String fieldPath,
javafx.beans.property.BooleanProperty property) |
void |
bindBidirectional(java.lang.String fieldPath,
javafx.beans.property.Property<java.lang.Number> property) |
<T> void |
bindBidirectional(java.lang.String fieldPath,
javafx.beans.property.Property<T> property,
java.lang.Class<T> propertyType)
Binds a
Property by traversing the bean's field tree |
void |
bindBidirectional(java.lang.String fieldPath,
javafx.beans.property.StringProperty property) |
<E> void |
bindContentBidirectional(java.lang.String fieldPath,
java.lang.String itemFieldPath,
java.lang.Class<?> itemFieldPathType,
javafx.collections.ObservableList<E> list,
java.lang.Class<E> listValueType,
javafx.scene.control.SelectionModel<E> selectionModel,
java.lang.String selectionModelItemMasterPath)
Binds a
ObservableList by traversing the bean's field tree. |
<K,V> void |
bindContentBidirectional(java.lang.String fieldPath,
java.lang.String itemFieldPath,
java.lang.Class<?> itemFieldPathType,
javafx.collections.ObservableMap<K,V> map,
java.lang.Class<V> mapValueType,
javafx.scene.control.SelectionModel<V> selectionModel,
java.lang.String selectionModelItemMasterPath)
Binds a
ObservableMap by traversing the bean's field tree. |
<E> void |
bindContentBidirectional(java.lang.String fieldPath,
java.lang.String itemFieldPath,
java.lang.Class<?> itemFieldPathType,
javafx.collections.ObservableSet<E> set,
java.lang.Class<E> setValueType,
javafx.scene.control.SelectionModel<E> selectionModel,
java.lang.String selectionModelItemMasterPath)
Binds a
ObservableSet by traversing the bean's field tree. |
javafx.beans.property.ObjectProperty<java.text.DateFormat> |
dateFormatProperty() |
javafx.beans.property.ReadOnlyObjectProperty<BeanPathAdapter.FieldPathValue> |
fieldPathValueProperty() |
B |
getBean() |
java.text.DateFormat |
getDateFormat() |
protected BeanPathAdapter.FieldBean<java.lang.Void,B> |
getRoot() |
boolean |
hasFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
Determines if the
BeanPathAdapter.FieldPathValueType (s) are being used by the
#notifyProperty() |
protected static <T> java.lang.Class<T> |
propertyValueClass(javafx.beans.property.Property<T> property)
Provides the underlying value class for a given
Property |
void |
removeFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
Removes
BeanPathAdapter.FieldPathValueType (s) BeanPathAdapter.FieldPathValueType (s) that
#notifyProperty() will use |
void |
setBean(B bean)
Sets the root bean of the
BeanPathAdapter . |
void |
setDateFormat(java.text.DateFormat df)
Sets the
dateFormatProperty() value |
<T> void |
unBindBidirectional(java.lang.String fieldPath,
javafx.beans.property.Property<T> property)
Unbinds a
Property by traversing the bean's field tree |
DateFormat
ObjectProperty
used for
Date
/ Calendar
conversions (defaults to
SDF
)ReadOnlyObjectProperty
that contains the last path
that was changed in the BeanPathAdapter
. For
notifications for items bound using content bindings
(collections/maps)addFieldPathValueTypes(FieldPathValueType...)
,
removeFieldPathValueTypes(FieldPathValueType...)
,
hasFieldPathValueTypes(FieldPathValueType...)
public static final char PATH_SEPARATOR
public static final char COLLECTION_ITEM_PATH_SEPARATOR
public static final java.text.DateFormat SDF
public BeanPathAdapter(B bean)
bean
- the bean the BeanPathAdapter
is forpublic void bindBidirectional(java.lang.String fieldPath, javafx.beans.property.BooleanProperty property)
public void bindBidirectional(java.lang.String fieldPath, javafx.beans.property.StringProperty property)
public void bindBidirectional(java.lang.String fieldPath, javafx.beans.property.Property<java.lang.Number> property)
public <E> void bindContentBidirectional(java.lang.String fieldPath, java.lang.String itemFieldPath, java.lang.Class<?> itemFieldPathType, javafx.collections.ObservableList<E> list, java.lang.Class<E> listValueType, javafx.scene.control.SelectionModel<E> selectionModel, java.lang.String selectionModelItemMasterPath)
ObservableList
by traversing the bean's field tree. An
additional item path can be specified when the path points to a
Collection
that contains beans that also need traversed in order
to establish the final value. For example: If a field path points to
phoneNumbers
(relative to the getBean()
) where
phoneNumbers
is a Collection
that contains
PhoneNumber
instances which in turn have a field called
areaCode
then an item path can be passed in addition to the
field path with areaCode
as it's value.fieldPath
- the .
separated field paths relative to
the getBean()
that will be traverseditemFieldPath
- the .
separated field paths relative to
each item in the bean's underlying Collection
that
will be traversed (empty/null when each item value does not
need traversed)itemFieldPathType
- the Class
of that the item path points tolist
- the ObservableList
to bind to the field class type of
the propertylistValueType
- the class type of the ObservableList
valueselectionModel
- the SelectionModel
used to set the values within the
ObservableList
only applicable when the
ObservableList
is used for selection(s) and therefore
cannot be updated directly because it is read-onlyselectionModelItemMasterPath
- when binding to SelectionModel
items, this will be the
optional path to the collection field that contains all the
items to select frompublic <E> void bindContentBidirectional(java.lang.String fieldPath, java.lang.String itemFieldPath, java.lang.Class<?> itemFieldPathType, javafx.collections.ObservableSet<E> set, java.lang.Class<E> setValueType, javafx.scene.control.SelectionModel<E> selectionModel, java.lang.String selectionModelItemMasterPath)
ObservableSet
by traversing the bean's field tree. An
additional item path can be specified when the path points to a
Collection
that contains beans that also need traversed in order
to establish the final value. For example: If a field path points to
phoneNumbers
(relative to the getBean()
) where
phoneNumbers
is a Collection
that contains
PhoneNumber
instances which in turn have a field called
areaCode
then an item path can be passed in addition to the
field path with areaCode
as it's value.fieldPath
- the .
separated field paths relative to
the getBean()
that will be traverseditemFieldPath
- the .
separated field paths relative to
each item in the bean's underlying Collection
that
will be traversed (empty/null when each item value does not
need traversed)itemFieldPathType
- the Class
of that the item path points toset
- the ObservableSet
to bind to the field class type of
the propertysetValueType
- the class type of the ObservableSet
valueselectionModel
- the SelectionModel
used to set the values within the
ObservableSet
only applicable when the
ObservableSet
is used for selection(s) and therefore
cannot be updated directly because it is read-onlyselectionModelItemMasterPath
- when binding to SelectionModel
items, this will be the
optional path to the collection field that contains all the
items to select frompublic <K,V> void bindContentBidirectional(java.lang.String fieldPath, java.lang.String itemFieldPath, java.lang.Class<?> itemFieldPathType, javafx.collections.ObservableMap<K,V> map, java.lang.Class<V> mapValueType, javafx.scene.control.SelectionModel<V> selectionModel, java.lang.String selectionModelItemMasterPath)
ObservableMap
by traversing the bean's field tree. An
additional item path can be specified when the path points to a
Collection
that contains beans that also need traversed in order
to establish the final value. For example: If a field path points to
phoneNumbers
(relative to the getBean()
) where
phoneNumbers
is a Collection
that contains
PhoneNumber
instances which in turn have a field called
areaCode
then an item path can be passed in addition to the
field path with areaCode
as it's value.fieldPath
- the .
separated field paths relative to
the getBean()
that will be traverseditemFieldPath
- the .
separated field paths relative to
each item in the bean's underlying Collection
that
will be traversed (empty/null when each item value does not
need traversed)itemFieldPathType
- the Class
of that the item path points tomap
- the ObservableMap
to bind to the field class type of
the propertymapValueType
- the class type of the ObservableMap
valueselectionModel
- the SelectionModel
used to set the values within the
ObservableMap
only applicable when the
ObservableMap
is used for selection(s) and therefore
cannot be updated directly because it is read-onlyselectionModelItemMasterPath
- when binding to SelectionModel
items, this will be the
optional path to the collection field that contains all the
items to select frompublic <T> void bindBidirectional(java.lang.String fieldPath, javafx.beans.property.Property<T> property, java.lang.Class<T> propertyType)
Property
by traversing the bean's field treefieldPath
- the .
separated field paths relative to
the getBean()
that will be traversedproperty
- the Property
to bind to the field class type of the
propertypropertyType
- the class type of the Property
valuepublic <T> void unBindBidirectional(java.lang.String fieldPath, javafx.beans.property.Property<T> property)
Property
by traversing the bean's field treefieldPath
- the .
separated field paths relative to
the getBean()
that will be traversedproperty
- the Property
to bind to the field class type of the
propertypublic B getBean()
BeanPathAdapter
public void setBean(B bean)
BeanPathAdapter
. Any existing
properties will be updated with the values relative to the paths within
the bean.bean
- the bean to setprotected final BeanPathAdapter.FieldBean<java.lang.Void,B> getRoot()
BeanPathAdapter.FieldBean
public void setDateFormat(java.text.DateFormat df)
dateFormatProperty()
valuedf
- the DateFormat
to setpublic java.text.DateFormat getDateFormat()
dateFormatProperty()
valuepublic javafx.beans.property.ObjectProperty<java.text.DateFormat> dateFormatProperty()
DateFormat
ObjectProperty
used for
Date
/ Calendar
conversions (defaults to
SDF
)public final javafx.beans.property.ReadOnlyObjectProperty<BeanPathAdapter.FieldPathValue> fieldPathValueProperty()
ReadOnlyObjectProperty
that contains the last path
that was changed in the BeanPathAdapter
. For
notifications for items bound using content bindings
(collections/maps)addFieldPathValueTypes(FieldPathValueType...)
,
removeFieldPathValueTypes(FieldPathValueType...)
,
hasFieldPathValueTypes(FieldPathValueType...)
protected static <T> java.lang.Class<T> propertyValueClass(javafx.beans.property.Property<T> property)
Property
property
- the Property
to checkProperty
public void addFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
BeanPathAdapter.FieldPathValueType
(s) BeanPathAdapter.FieldPathValueType
(s) that
#notifyProperty()
will usetypes
- the BeanPathAdapter.FieldPathValueType
to addpublic void removeFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
BeanPathAdapter.FieldPathValueType
(s) BeanPathAdapter.FieldPathValueType
(s) that
#notifyProperty()
will usetypes
- the BeanPathAdapter.FieldPathValueType
(s) to removepublic boolean hasFieldPathValueTypes(BeanPathAdapter.FieldPathValueType... types)
BeanPathAdapter.FieldPathValueType
(s) are being used by the
#notifyProperty()
types
- the BeanPathAdapter.FieldPathValueType
(s) to check forBeanPathAdapter.FieldPathValueType
(s) exist