[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-openjfx-dev
Subject:    ListProperty and ListBinding
From:       zonski () googlemail ! com (Daniel Zwolenski)
Date:       2011-12-21 20:01:54
Message-ID: B67AE664-72F4-4C5E-9009-2C2DF103A321 () gmail ! com
[Download RAW message or body]

Just a quick one: will list merging be supported out-of-the-box as part of list \
binding? I have a couple of cases where I need to merge several sublists into one \
parent list and it's a bit messy to implement. 

Some of the challenges include working out which items in the parent list are from \
which sublist (needed to bind a remove), especially if the same item can be in more \
than one sublist. Also: in this case should the item only appear once or multiple \
times in the parent list (probably needs to be a configurable option); how to do \
post-merge sorting; once bound I probably shouldnt be able to manually edit the \
parent list - remove in particular would be weird; 

Bidirectional binding is not achievable in this case either really. 

Just some general things to watch out for in this area. I suspect there will be \
similar or worse challenges with more complex list binding expressions (eg \
intersection, disjunction, etc). Am I being optimistic in hoping some/most of these \
will be part of jfx core, rather than left to developers?


On 22/12/2011, at 3:06 AM, Michael Heinrichs <michael.heinrichs at oracle.com> wrote:

> Hi Richard,
> 
> as I did not get any other suggestion, my understanding is, that this proposal was \
> accepted. 
> Thanks,
> Michael
> 
> 
> 
> On 19.12.2011, at 16:46, Michael Heinrichs wrote:
> 
> > Yeah, I know. As you know, this is more of a hack, because size() and isEmpty(), \
> > which would feel more natural, are not available. Any other suggestion? 
> > - Michael
> > 
> > 
> > 
> > On 17.12.2011, at 01:38, Richard Bair wrote:
> > 
> > > As usual, I think this has been really well thought out. I get a little \
> > > concerned over sizeProperty and emptyProperty just because it seems out of \
> > > place. I'm good with this change though, and excited to have the ability to \
> > > bind lists! 
> > > Richard
> > > 
> > > On Dec 15, 2011, at 6:49 AM, Michael Heinrichs wrote:
> > > 
> > > > Hi,
> > > > 
> > > > the last couple of days, I have mainly worked on the design to close the gap \
> > > > between the binding API and our observable collections. Here is the proposal. \
> > > > I am only talking about ObservableList, the other collections would be \
> > > > treaded similar. 
> > > > public interface ObservableListValue<E> extends \
> > > > ObservableObjectValue<ObservableList<E>>, ObservableList<E> {} public \
> > > > interface WritableListValue<E> extends \
> > > > WritableObjectValue<ObservableList<E>>, ObservableList<E> {} 
> > > > Notice that this is different than all other ObservableValues and \
> > > > WritableValues, that we have so far, because ObservableListValue and \
> > > > WritableListValue also extend ObservableList. A "real" ObservableList and \
> > > > implementations of ObservableListValue/WritableListValue have a lot in \
> > > > common, while playing with the prototype I often found myself writing the \
> > > > same functionality for both types. By making \
> > > > ObservableListValue/WritableListValue extend ObservableList, this became a \
> > > > lot easier. To implement the List functionality, ObservableListValue and \
> > > > WritableListValue simply forward the call to the referenced ObservableList. \
> > > > If they reference null, it is treaded like an immutable empty list. 
> > > > Next element in the hierarchy is the ListExpression. As with other expression \
> > > > classes, it is the super class of list bindings and list properties. It \
> > > > provides as much common functionality as possible without using any fields. \
> > > > This is left to the actual implementations. In more detail, it implements all \
> > > > List methods, adds some methods for the fluent API and defines two \
> > > > properties: size and empty. For size I also added a getSize() method to \
> > > > follow Java Bean conventions more closely. (The method isEmpty() is already \
> > > > defined in List.) 
> > > > public abstract class ListExpression<E> implements ObservableListValue<E> {
> > > > public static <E> ListExpression<E> listExpression(final \
> > > > ObservableListValue<E> value) {...} 
> > > > public abstract int getSize();
> > > > public abstract ReadOnlyIntegerProperty sizeProperty();
> > > > 
> > > > public abstract ReadOnlyBooleanProperty emptyProperty();
> > > > 
> > > > public ObjectBinding<E> valueAt(int index) {...}
> > > > public ObjectBinding<E> valueAt(ObservableIntegerValue index) {...}
> > > > 
> > > > public BooleanBinding isEqualTo(final ObservableList<?> other) {...}
> > > > public BooleanBinding isNotEqualTo(final ObservableList<?> other) {...}
> > > > 
> > > > public BooleanBinding isNull() {...}
> > > > public BooleanBinding isNotNull() {...}
> > > > 
> > > > public StringBinding asString() {...}
> > > > }
> > > > 
> > > > ListBinding allows to define custom list bindings exactly as you would for \
> > > > all other types: 
> > > > public abstract class ListBinding<E> extends ListExpression<E> implements \
> > > > Binding<ObservableList<E>> {...} 
> > > > The class ReadOnlyListProperty defines the functionality of a read only \
> > > > property that references a list. It provides as much functionality as \
> > > > possible without using a field. It is very similar to other read only \
> > > > properties, but in addition it has four new methods to define a \
> > > > content-binding. A content binding means, that the values are copied from one \
> > > > list to another. This way a read only property like Group.children can be \
> > > > bound to other lists. 
> > > > public abstract class ReadOnlyListProperty<E> extends ListExpression<E> \
> > > > implements ReadOnlyProperty<ObservableList<E>>  { public void \
> > > > bindContentBidirectional(ObservableList<E> list) {...} public void \
> > > > unbindContentBidirectional(Object object) {...} 
> > > > public void bindContent(ObservableList<E> list) {...}
> > > > public void unbindContent(Object object) {...}
> > > > }
> > > > 
> > > > The class ReadOnlyListPropertyBase is similar to other ReadOnlyPropertyBase \
> > > > classes. The main difference is, that there are two fireValueChangedEvent \
> > > > methods() that you have to call. The usual method without parameters needs to \
> > > > be called, if the reference changes, the second method that takes a Change \
> > > > object needs to be called, every time the referenced list itself changes: 
> > > > public abstract class ReadOnlyListPropertyBase<E> extends \
> > > > ReadOnlyListProperty<E> { protected void fireValueChangedEvent() {...}
> > > > protected void fireValueChangedEvent(ListChangeListener.Change<? extends E> \
> > > > change) {...} }
> > > > 
> > > > I think the classes ReadOnlyListWrapper, ListProperty, ListPropertyBase, and \
> > > > SimpleListProperty really work exactly like the classes for the other types. 
> > > > public class ReadOnlyListWrapper<E> extends SimpleListProperty<E> {...}
> > > > 
> > > > public abstract class ListProperty<E> extends ReadOnlyListProperty<E> \
> > > > implements Property<ObservableList<E>>, WritableListValue<E> {...} 
> > > > public abstract class ListPropertyBase<E> extends ListProperty<E> {...}
> > > > 
> > > > public class SimpleListProperty<E> extends ListPropertyBase<E> {...}
> > > > 
> > > > The class Bindings will get a bunch of new methods:
> > > > public static <E> void bindContentBidirectional(ObservableList<E> list1, \
> > > > ObservableList<E> list2) {...} public static void \
> > > > unbindContentBidirectional(Object obj1, Object obj2) {...} 
> > > > public static <E> void bindContent(List<E> list1, ObservableList<? extends E> \
> > > > list2) {...} public static void unbindContent(Object obj1, Object obj2) {...}
> > > > 
> > > > public static <E> IntegerBinding size(final ObservableList<E> op) {...}
> > > > public static <E> BooleanBinding isEmpty(final ObservableList<E> op) {...}
> > > > 
> > > > public static <E> ObjectBinding<E> valueAt(final ObservableList<E> op, final \
> > > > int index) {...} public static <E> ObjectBinding<E> valueAt(final \
> > > > ObservableList<E> op, final ObservableIntegerValue index) {...} 
> > > > public static BooleanBinding booleanValueAt(final ObservableList<Boolean> op, \
> > > > final int index) {...} public static BooleanBinding booleanValueAt(final \
> > > > ObservableList<Boolean> op, final ObservableIntegerValue index) {...} 
> > > > public static DoubleBinding doubleValueAt(final ObservableList<? extends \
> > > > Number> op, final int index) {...} public static DoubleBinding \
> > > > doubleValueAt(final ObservableList<? extends Number> op, final \
> > > > ObservableIntegerValue index) {...} 
> > > > public static FloatBinding floatValueAt(final ObservableList<? extends \
> > > > Number> op, final int index) {...} public static FloatBinding \
> > > > floatValueAt(final ObservableList<? extends Number> op, final \
> > > > ObservableIntegerValue index) {...} 
> > > > public static IntegerBinding integerValueAt(final ObservableList<? extends \
> > > > Number> op, final int index) {...} public static IntegerBinding \
> > > > integerValueAt(final ObservableList<? extends Number> op, final \
> > > > ObservableIntegerValue index) {...} 
> > > > public static LongBinding longValueAt(final ObservableList<? extends Number> \
> > > > op, final int index) {...} public static LongBinding longValueAt(final \
> > > > ObservableList<? extends Number> op, final ObservableIntegerValue index) \
> > > > {...} 
> > > > public static StringBinding stringValueAt(final ObservableList<? extends \
> > > > Number> op, final int index) {...} public static StringBinding \
> > > > stringValueAt(final ObservableList<? extends Number> op, final \
> > > > ObservableIntegerValue index) {...} 
> > > > Any thoughts?
> > > > 
> > > > Thanks,
> > > > Michael
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > > 
> > > 
> > 
> 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic