This discussion is archived
8 Replies Latest reply: Nov 28, 2012 9:00 PM by SaiPradeepDandem RSS

How to use ListBinding ?

SaiPradeepDandem Explorer
Currently Being Moderated
Hi,
I have a requirement where I want to use ListBinding.
I have an observable list of objects (say Employee.java which contains id, firstName, Lastname as its properties.)
I want to bind/create all the firstName s to a separate list, by using binding to the main list of objects.

So that
* Whenever a new Employee object is added into main list, the second list also updates automatically.
* Whenever the firstName of any Employee object is modified in the main list, the second list also updates accordingly.

Can I get the second list (List of firstName s) by using ListBinding.? If yes can anyone please give some inputs how to achieve this.?

Thanks in advance !!


Regards,
Sai Pradeep Dandem.
  • 1. Re: How to use ListBinding ?
    975590 Newbie
    Currently Being Moderated
    Hi,

    I am not sure if I have understood your meaning :)
    You want to get a list(list 1) which only has "firstName" from a list(list 2) which has the whole objects, and list 1 can be changed when list 2 is changed?

    The list here you mean is just a kind of data structrue? or it is ListView?
    If you mean ListView, I think it may be a simple question. :)
  • 2. Re: How to use ListBinding ?
    SaiPradeepDandem Explorer
    Currently Being Moderated
    Hi,
    Sorry for the confusion.

    I want to get an ObservableList(list-1) which only has "firstName" from another ObservableList(list-2) which has the whole Employee objects, and list-1 can be changed when list-2 is changed?

    In other words I want to maintain list-1 by using binding with list-2.(may be ListBinding)

    Thanks & Regards,
    Sai Pradeep Dandem.
  • 3. Re: How to use ListBinding ?
    975590 Newbie
    Currently Being Moderated
    Hi,

    I am sorry that I don't have any idea about ListBinding.
    (Maybe you can implement it by using observer design pattern, register list-1 to list-2, when list-2 changes, notice list-1, and let list-1 do the same kind changes~~haa, it sounds like a "stupid" method, there exists ObservableList already! :) )

    Hope someone else will help you!
  • 4. Re: How to use ListBinding ?
    James_D Guru
    Currently Being Moderated
    What are your exact requirements here?

    If you want a plain old java.util.List<String> for your list of first names, then your best bet is probably not to use binding at all, but to define a wrapper class that implements List<String> and simply references into the List<Person> for its accessor methods. This might be as simple as
    import java.util.AbstractList;
    import javafx.collections.ObservableList;
    
    public class FirstNameList extends AbstractList<String> {
      private final ObservableList<Person> personList ;
      public FirstNameList(ObservableList<Person> personList) {
        this.personList = personList ;
      }
      @Override
      public String get(int index) {
        return personList.get(index).getFirstName();
      }
      @Override
      public int size() {
        return personList.size();
      }
    }
    If you want an ObservableList<String> for your list of first names, the same approach should work, but managing listener notification on the wrapper might be somewhat tricky.

    If you're using the list of first names just to display in another control (the most common use case for needing an ObservableList), then the best bet might be to make the control reference your ObservableList<Person> and customize the control's cells to only display the first name.

    Edited by: James_D on Nov 28, 2012 5:21 AM (Added code example)
  • 5. Re: How to use ListBinding ?
    shakir.gusaroff Expert
    Currently Being Moderated
    Hi. There is Bindings. bindContentBidirectional(list1, list2);
    But list1 and list2 should be the same type of object. This is not appropriate for you.
    I think for your case Map is more suitable.
    Key: Employee.firstname
    Value:Employee
    Then add a mapchangeListener to your ObservableMap
    http://docs.oracle.com/javafx/2/api/javafx/collections/MapChangeListener.html
  • 6. Re: How to use ListBinding ?
    James_D Guru
    Currently Being Moderated
    Ah, even with the simple FirstNameList I made above, you can (sort of) create an ObservableList<String> from it. It's not very efficient, because the list is rebuilt on each change, but it should work.
    final ObservableList<Person> data = ... ;
    final List<String> firstNames = new FirstNameList(data);
    ObservableList<String> observableFirstNames = new ListBinding<String>() {
      { super.bind(data); }
      protected ObservableList<String> computeValue() {
         return FXCollections.observableArrayList(firstNames);
      }
    };
  • 7. Re: How to use ListBinding ?
    James_D Guru
    Currently Being Moderated
    At some point, I might actually learn to think everything through before posting a single solution, instead of incrementally making my solutions better.

    I made a more general version of the whole thing. Here's a DependentList<T,S> which implements a list of type S, based on a list of type T. You specify a Callback<T,S> to determine how to get an element of type S from an element of type T in the original list. In your case T is Employee, S is String, and the Callback is implemented as

    return employee.getFirstName();

    DependentList.java
    import java.util.AbstractList;
    import java.util.List;
    
    import javafx.beans.binding.ListBinding;
    import javafx.collections.FXCollections;
    import javafx.collections.ListChangeListener;
    import javafx.collections.ObservableList;
    import javafx.util.Callback;
    
    public class DependentList<T, S> extends AbstractList<S> {
      
      private final ObservableList<T> data ;
      private final Callback<T,S> callback ;
      private final ListBinding<S> binding ;
      
      public DependentList(ObservableList<T> data, Callback<T, S> callback) {
        this.data = data ;
        this.callback = callback ;
        this.binding = new ListBinding<S>() {
          {super.bind(DependentList.this.data);}
          @Override
          protected ObservableList<S> computeValue() {
            return FXCollections.observableArrayList(DependentList.this);
          }
        };
      }
    
      @Override
      public S get(int index) {
        return callback.call(data.get(index));
      }
    
      @Override
      public int size() {
        return data.size();
      }
      
      // TODO: not a very efficient implementation
      public ObservableList<S> asObservableList() {
        return binding ;
      }
      
    }
    Usage example:
        ObservableList<Person> personList = FXCollections.observableArrayList(); // populate
    
        // To get a List of the firstNames:
    
        List<String> firstNameList = new DependentList<Person, String>(personList, new Callback<Person, String>() {
          @Override
          public String call(Person person) {
            return person.getFirstName();
          }
        });
    
        // To get an ObservableList of the firstNames:
    
        ObservableList<String> observableFirstNames = new DependentList<Person, String>(personList, new Callback<Person, String>() {
          @Override
          public String call(Person person) {
            return person.getFirstName();
          }
        }).asObservableList();
  • 8. Re: How to use ListBinding ?
    SaiPradeepDandem Explorer
    Currently Being Moderated
    Hi James,
    Thanks for your inputs :)
    I will check this whether it will solve my requirement. Thanks a lot !! :)

    Thanks & Regards,
    Sai Pradeep Dandem.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points