TransformedList question

View: New views
9 Messages — Rating Filter:   Alert me  

TransformedList question

by wsnyder6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi

Love glazed lists. Been following the Tutorials on the wiki. I am working thru Tutorial5, which deals with a TransformedList.

What if each Issue could have more than one User attached to it? How then would I implement the TransformedList with Dynamic filtering?  

I am working on an application where I need to do something like this - but I am not sure how to do it? Anyone ever tackle this problem?

Parent Message unknown Re: TransformedList question

by Holger Brands :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

>
> What if each Issue could have more than one User attached to it? How then
> would I implement the TransformedList with Dynamic filtering?  
>

The tutorial shows filtering of issues by the issue reporter: Issue.getReporter()
For the following discussion let's assume you want to filter by
all users of the issue as defined by method Issue.getAllUsers().

You would have to change
a) the IssueToUserList from tutorial chapter 4
b) the IssuesForUsersMatcher from tutorial chapter 5.

a) Instead of using the IssueToUserList I would use a CollectionList like this:

CollectionList<Issue, String> usersNonUnique = new CollectionList<Issue, String>(source, new IssueToUsersModel());


/**
 * Determines all users for an issue.
 */
public class IssueToUsersModel implements CollectionList.Model<Issue, String> {
    public List<String> getChildren(Issue issue) {
        return issue.getAllUsers();
    }
}

The CollectionList is a TransformedList that maps each issue from the source list to the associated users.
It's a kind of parent-child relationship.


b) IssuesForUsersMatcher should be changed to match all issue users using. Issue.getAllUsers():

   /**
    * Test whether to include or not include the specified issue based
    * on whether or not their user is selected.
    */
   public boolean matches(Object o) {
       if(o == null) return false;
       if(users.isEmpty()) return true;
       
       Issue issue = (Issue)o;
       for (Iterator i = issue.getAllUsers().iterator(); i.hasNext(); ) {
         if(users.contains(i.next())) return true;
       }
       return false;
    }


Hope this helps,
Holger

__________________________________________________________________________
Erweitern Sie FreeMail zu einem noch leistungsstärkeren E-Mail-Postfach!
Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: TransformedList question

by wsnyder6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Awesome. I will try this.

I also thought that I could use the TransformedList like such:

 class ItemsToLabelsList extends TransformedList {
       
        public IssuesToUsersList(EventList source) {
            super(source);
            for (Object elem : source) {
                addAll( ((Issue)elem).getUsers() );
            }
            source.addListEventListener(this);
        }
       
        public void listChanged(ListEvent listChanges) {
            updates.forwardEvent(listChanges);
        }

    }

Holger Brands-2 wrote:
Hi,

>
> What if each Issue could have more than one User attached to it? How then
> would I implement the TransformedList with Dynamic filtering?  
>

The tutorial shows filtering of issues by the issue reporter: Issue.getReporter()
For the following discussion let's assume you want to filter by
all users of the issue as defined by method Issue.getAllUsers().

You would have to change
a) the IssueToUserList from tutorial chapter 4
b) the IssuesForUsersMatcher from tutorial chapter 5.

a) Instead of using the IssueToUserList I would use a CollectionList like this:

CollectionList<Issue, String> usersNonUnique = new CollectionList<Issue, String>(source, new IssueToUsersModel());


/**
 * Determines all users for an issue.
 */
public class IssueToUsersModel implements CollectionList.Model<Issue, String> {
    public List<String> getChildren(Issue issue) {
        return issue.getAllUsers();
    }
}

The CollectionList is a TransformedList that maps each issue from the source list to the associated users.
It's a kind of parent-child relationship.


b) IssuesForUsersMatcher should be changed to match all issue users using. Issue.getAllUsers():

   /**
    * Test whether to include or not include the specified issue based
    * on whether or not their user is selected.
    */
   public boolean matches(Object o) {
       if(o == null) return false;
       if(users.isEmpty()) return true;
       
       Issue issue = (Issue)o;
       for (Iterator i = issue.getAllUsers().iterator(); i.hasNext(); ) {
         if(users.contains(i.next())) return true;
       }
       return false;
    }


Hope this helps,
Holger

__________________________________________________________________________
Erweitern Sie FreeMail zu einem noch leistungsstärkeren E-Mail-Postfach!
Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
For additional commands, e-mail: users-help@glazedlists.dev.java.net

Re: Re: TransformedList question

by Jesse Wilson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 8/15/06, wsnyder6 <wsnyder6@...> wrote:

> I also thought that I could use the TransformedList like such:
>  class ItemsToLabelsList extends TransformedList {
>         public IssuesToUsersList(EventList source) {
>             super(source);
>             for (Object elem : source) {
>                 addAll( ((Issue)elem).getUsers() );
>             }
>             source.addListEventListener(this);
>         }
>         public void listChanged(ListEvent listChanges) {
>             updates.forwardEvent(listChanges);
>         }
>     }

Unforunately, this won't work since the TransformedList needs
to map indices from one list to another. For example, the addAll()
method won't work - it will just call through to source.

Regardless, CollectionList does what you want. Let us know
if you run into further problems!

Cheers,
Jesse

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


Re: TransformedList question

by James Lemieux :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Holger has it exactly right. CollectionList is the de facto list to use when a single source element produces multiple transformed elements. Using CollectionList is the first half of the solution.

The second half is the TextFilterator which extracts Strings from the Issues to be considered when filtering any given Issue. That TextFilterator needs to return all users as Strings in addition to any other Strings you deem worthy of consideration when filtering your Issues. Again, Holger has sketched the code well.

I'd urge you to check out our screencasts here:

http://www.publicobject.com/glazedlistsdeveloper/

as they do a good job of introducing each concept separate and apart from each other. The screencast of FilterList may be particularly useful to you.

James

On 8/15/06, wsnyder6 <wsnyder6@...> wrote:

Awesome. I will try this.

I also thought that I could use the TransformedList like such:

class ItemsToLabelsList extends TransformedList {

        public IssuesToUsersList(EventList source) {
            super(source);
            for (Object elem : source) {
                addAll( ((Issue)elem).getUsers() );
            }
            source.addListEventListener(this);
        }

        public void listChanged(ListEvent listChanges) {
            updates.forwardEvent(listChanges);
        }

    }


Holger Brands-2 wrote:

>
> Hi,
>
>>
>> What if each Issue could have more than one User attached to it? How then
>> would I implement the TransformedList with Dynamic filtering?
>>
>
> The tutorial shows filtering of issues by the issue reporter:
> Issue.getReporter()
> For the following discussion let's assume you want to filter by
> all users of the issue as defined by method Issue.getAllUsers().
>
> You would have to change
> a) the IssueToUserList from tutorial chapter 4
> b) the IssuesForUsersMatcher from tutorial chapter 5.
>
> a) Instead of using the IssueToUserList I would use a CollectionList like
> this:
>
> CollectionList<Issue, String> usersNonUnique = new CollectionList<Issue,
> String>(source, new IssueToUsersModel());
>
>
> /**
>  * Determines all users for an issue.
>  */
> public class IssueToUsersModel implements CollectionList.Model<Issue,
> String> {
>     public List<String> getChildren(Issue issue) {
>         return issue.getAllUsers();
>     }
> }
>
> The CollectionList is a TransformedList that maps each issue from the
> source list to the associated users.
> It's a kind of parent-child relationship.
>
>
> b) IssuesForUsersMatcher should be changed to match all issue users using.
> Issue.getAllUsers():
>
>    /**
>     * Test whether to include or not include the specified issue based
>     * on whether or not their user is selected.
>     */
>    public boolean matches(Object o) {
>        if(o == null) return false;
>        if(users.isEmpty()) return true;
>
>        Issue issue = (Issue)o;
>        for (Iterator i = issue.getAllUsers().iterator(); i.hasNext(); ) {
>          if(users.contains(i.next())) return true;
>        }
>        return false;
>     }
>
>
> Hope this helps,

> Holger
>
> __________________________________________________________________________
> Erweitern Sie FreeMail zu einem noch leistungsstärkeren E-Mail-Postfach!
> Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@...
> For additional commands, e-mail: users-help@...
>
>
>

--
View this message in context: http://www.nabble.com/TransformedList-question-tf2110350.html#a5820094
Sent from the GlazedLists - User forum at Nabble.com.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...



Re: TransformedList question

by wsnyder6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks, I have to check out the screencast.

Holger's code worked great. It is awesome how this stuff just 'works'. Very nice library.

James Lemieux wrote:
Holger has it exactly right. CollectionList is the de facto list to use when
a single source element produces multiple transformed elements. Using
CollectionList is the first half of the solution.

The second half is the TextFilterator which extracts Strings from the Issues
to be considered when filtering any given Issue. That TextFilterator needs
to return all users as Strings in addition to any other Strings you deem
worthy of consideration when filtering your Issues. Again, Holger has
sketched the code well.

I'd urge you to check out our screencasts here:

http://www.publicobject.com/glazedlistsdeveloper/

as they do a good job of introducing each concept separate and apart from
each other. The screencast of FilterList may be particularly useful to you.

James

On 8/15/06, wsnyder6 <wsnyder6@gmail.com> wrote:
>
>
> Awesome. I will try this.
>
> I also thought that I could use the TransformedList like such:
>
> class ItemsToLabelsList extends TransformedList {
>
>         public IssuesToUsersList(EventList source) {
>             super(source);
>             for (Object elem : source) {
>                 addAll( ((Issue)elem).getUsers() );
>             }
>             source.addListEventListener(this);
>         }
>
>         public void listChanged(ListEvent listChanges) {
>             updates.forwardEvent(listChanges);
>         }
>
>     }
>
>
> Holger Brands-2 wrote:
> >
> > Hi,
> >
> >>
> >> What if each Issue could have more than one User attached to it? How
> then
> >> would I implement the TransformedList with Dynamic filtering?
> >>
> >
> > The tutorial shows filtering of issues by the issue reporter:
> > Issue.getReporter()
> > For the following discussion let's assume you want to filter by
> > all users of the issue as defined by method Issue.getAllUsers().
> >
> > You would have to change
> > a) the IssueToUserList from tutorial chapter 4
> > b) the IssuesForUsersMatcher from tutorial chapter 5.
> >
> > a) Instead of using the IssueToUserList I would use a CollectionList
> like
> > this:
> >
> > CollectionList<Issue, String> usersNonUnique = new CollectionList<Issue,
> > String>(source, new IssueToUsersModel());
> >
> >
> > /**
> >  * Determines all users for an issue.
> >  */
> > public class IssueToUsersModel implements CollectionList.Model<Issue,
> > String> {
> >     public List<String> getChildren(Issue issue) {
> >         return issue.getAllUsers();
> >     }
> > }
> >
> > The CollectionList is a TransformedList that maps each issue from the
> > source list to the associated users.
> > It's a kind of parent-child relationship.
> >
> >
> > b) IssuesForUsersMatcher should be changed to match all issue users
> using.
> > Issue.getAllUsers():
> >
> >    /**
> >     * Test whether to include or not include the specified issue based
> >     * on whether or not their user is selected.
> >     */
> >    public boolean matches(Object o) {
> >        if(o == null) return false;
> >        if(users.isEmpty()) return true;
> >
> >        Issue issue = (Issue)o;
> >        for (Iterator i = issue.getAllUsers().iterator(); i.hasNext(); )
> {
> >          if(users.contains(i.next())) return true;
> >        }
> >        return false;
> >     }
> >
> >
> > Hope this helps,
> > Holger
> >
> >
> __________________________________________________________________________
> > Erweitern Sie FreeMail zu einem noch leistungsstärkeren E-Mail-Postfach!
> > Mehr Infos unter http://freemail.web.de/home/landingpad/?mc=021131
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
> > For additional commands, e-mail: users-help@glazedlists.dev.java.net
> >
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/TransformedList-question-tf2110350.html#a5820094
> Sent from the GlazedLists - User forum at Nabble.com.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
> For additional commands, e-mail: users-help@glazedlists.dev.java.net
>
>

Re: Re: TransformedList question

by wsnyder6 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yes. I see that it didn't work. But the CollectionList did. Sweet!

Taking this one step further, what if User was a hierarchical object? Is it possible to have a JTree (instead of a JList) to hold a User hierarchy for filtering?

Hmm, Maybe a 'Category' object would be a better example. So if I clicked on 'All Categories' I would see all Issues. If I clicked on Category A, I would see Category A and Category B issues, etc...

All Categories
+--Category A
  +--Category B
+--Category C

Does GlazedLists have a TreeModel/SelectionListener that would do something like this?

Thanks for all your gracious help!

--Bill

Jesse Wilson wrote:
On 8/15/06, wsnyder6 <wsnyder6@gmail.com> wrote:
> I also thought that I could use the TransformedList like such:
>  class ItemsToLabelsList extends TransformedList {
>         public IssuesToUsersList(EventList source) {
>             super(source);
>             for (Object elem : source) {
>                 addAll( ((Issue)elem).getUsers() );
>             }
>             source.addListEventListener(this);
>         }
>         public void listChanged(ListEvent listChanges) {
>             updates.forwardEvent(listChanges);
>         }
>     }

Unforunately, this won't work since the TransformedList needs
to map indices from one list to another. For example, the addAll()
method won't work - it will just call through to source.

Regardless, CollectionList does what you want. Let us know
if you run into further problems!

Cheers,
Jesse

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
For additional commands, e-mail: users-help@glazedlists.dev.java.net

Re: Re: TransformedList question

by chaddaniels :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
I am using this method to have my users filter a list and the filtering is working beautifully.  However, I am running into a usability issue from my user's point of view.  The following contrived example will hopefully illustrate the problem.

Let's say I have an ObservableElementList of Cars, and an EventTableModel that displays them.  The end goal is that the user will be able to sort the table by Car Features.  So I have a CollectionList that maps Car object to their Features, and that is wrapped in a UniqueList that I display to the user for filtering.  The user is able to select a Feature from the displayed UniqueList of Features, and the table of Cars displayed gets filtered appropriately.  Now let's also say that each Car has a Color attribute that I allow the user to modify, and this Color attribute is completely independent of Features.  So far, so good.

This where the problem comes in.  If the user is actively filtering on a Feature that exists only in a single car, lets call it Car A, and if they edit the Color of Car A, then the following problem occurs.  Since Cars are observable, the Car ObservableElementList auto-updates, which leads to listChanged.  The CollectionList responds to the listChanged event on its parent list, but instead of doing an update like the parent list, it does a remove and then an add of Car A.  When this happens, Car A's Features are temporarily removed and then put back to the Feature list.  This in itself is not a problem because the user cannot see the Features getting removed and put back, but their selection of Features disappears, which they do notice.  When the selection disappears then of course that filter is removed and the table of Cars then becomes completely unfiltered.  

Am I doing something wrong here?  Is there a way to work around this issue?

Thanks up front for any help!

Chad




Yes. I see that it didn't work. But the CollectionList did. Sweet!

Taking this one step further, what if User was a hierarchical object? Is it possible to have a JTree (instead of a JList) to hold a User hierarchy for filtering?

Hmm, Maybe a 'Category' object would be a better example. So if I clicked on 'All Categories' I would see all Issues. If I clicked on Category A, I would see Category A and Category B issues, etc...

All Categories
+--Category A
  +--Category B
+--Category C

Does GlazedLists have a TreeModel/SelectionListener that would do something like this?

Thanks for all your gracious help!

--Bill

Jesse Wilson wrote:
On 8/15/06, wsnyder6 <wsnyder6@gmail.com> wrote:
> I also thought that I could use the TransformedList like such:
>  class ItemsToLabelsList extends TransformedList {
>         public IssuesToUsersList(EventList source) {
>             super(source);
>             for (Object elem : source) {
>                 addAll( ((Issue)elem).getUsers() );
>             }
>             source.addListEventListener(this);
>         }
>         public void listChanged(ListEvent listChanges) {
>             updates.forwardEvent(listChanges);
>         }
>     }

Unforunately, this won't work since the TransformedList needs
to map indices from one list to another. For example, the addAll()
method won't work - it will just call through to source.

Regardless, CollectionList does what you want. Let us know
if you run into further problems!

Cheers,
Jesse

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glazedlists.dev.java.net
For additional commands, e-mail: users-help@glazedlists.dev.java.net


re[3]: TransformedList question

by Kevin Day-7 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Some parts of this message have been removed. Learn more about Nabble's security policy.
So the core issue is that CollectionList is removing and adding instead of updating?  But the only reason an Update event is being received is because some other change to the object (completely unrelated to the Features of the Car) triggers an event change.
 
the problem source code here is in CollectionList.listChanged:
 

// treat like a delete and then an add:

    } else if(type == ListEvent.UPDATE) {

        handleDelete(index);

        handleInsert(index);

    }

 
 
 
A couple of things come to mind as potential solution vectors (one within your control, one definitely not):
 
1.  don't include the OEL in the chain leading to the CollectionList (this may or may not be possible - but if you can do it, it should nail the immediate problem)
2.  Maybe CollectionList needs a check to see if the model returns the exact same object (using an identity check), and that object is itself an EventList.  If it does, then there would be no need to actually perform an update of the CollectionList, and the UPDATE event could be ignored.  The problem with this strategy is that the easy implementation (adding a check to listChanged) would result in model.getChildren() being called twice for every change.  Definitely not desirable.
 
I'm interested to hear other folks' thoughts on this...
 
- K
 
----------------------- Original Message -----------------------
  
From: chaddaniels chad.dorkin@...
Cc: 
Date: Fri, 26 Jun 2009 14:14:34 -0700 (PDT)
Subject: Re: Re: TransformedList question
  

Hi,
I am using this method to have my users filter a list and the filtering is
working beautifully.  However, I am running into a usability issue from my
user's point of view.  The following contrived example will hopefully
illustrate the problem.

Let's say I have an ObservableElementList of Cars, and an EventTableModel
that displays them.  The end goal is that the user will be able to sort the
table by Car Features.  So I have a CollectionList that maps Car object to
their Features, and that is wrapped in a UniqueList that I display to the
user for filtering.  The user is able to select a Feature from the displayed
UniqueList of Features, and the table of Cars displayed gets filtered
appropriately.  Now let's also say that each Car has a Color attribute that
I allow the user to modify, and this Color attribute is completely
independent of Features.  So far, so good.

This where the problem comes in.  If the user is actively filtering on a
Feature that exists only in a single car, lets call it Car A, and if they
edit the Color of Car A, then the following problem occurs.  Since Cars are
observable, the Car ObservableElementList auto-updates, which leads to
listChanged.  The CollectionList responds to the listChanged event on its
parent list, but instead of doing an update like the parent list, it does a
remove and then an add of Car A.  When this happens, Car A's Features are
temporarily removed and then put back to the Feature list.  This in itself
is not a problem because the user cannot see the Features getting removed
and put back, but their selection of Features disappears, which they do
notice.  When the selection disappears then of course that filter is removed
and the table of Cars then becomes completely unfiltered.  

Am I doing something wrong here?  Is there a way to work around this issue?

Thanks up front for any help!

Chad




wsnyder6 wrote:

>
> Yes. I see that it didn't work. But the CollectionList did. Sweet!
>
> Taking this one step further, what if User was a hierarchical object? Is
> it possible to have a JTree (instead of a JList) to hold a User hierarchy
> for filtering?
>
> Hmm, Maybe a 'Category' object would be a better example. So if I clicked
> on 'All Categories' I would see all Issues. If I clicked on Category A, I
> would see Category A and Category B issues, etc...
>
> All Categories
> +--Category A
>   +--Category B
> +--Category C
>
> Does GlazedLists have a TreeModel/SelectionListener that would do
> something like this?
>
> Thanks for all your gracious help!
>
> --Bill
>
>
> Jesse Wilson wrote:
>>
>> On 8/15/06, wsnyder6 wsnyder6@... wrote:
>>> I also thought that I could use the TransformedList like such:
>>>  class ItemsToLabelsList extends TransformedList {
>>>         public IssuesToUsersList(EventList source) {
>>>             super(source);
>>>             for (Object elem : source) {
>>>                 addAll( ((Issue)elem).getUsers() );
>>>             }
>>>             source.addListEventListener(this);
>>>         }
>>>         public void listChanged(ListEvent listChanges) {
>>>             updates.forwardEvent(listChanges);
>>>         }
>>>     }
>>
>> Unforunately, this won't work since the TransformedList needs
>> to map indices from one list to another. For example, the addAll()
>> method won't work - it will just call through to source.
>>
>> Regardless, CollectionList does what you want. Let us know
>> if you run into further problems!
>>
>> Cheers,
>> Jesse
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@...
>> For additional commands, e-mail: users-help@...
>>
>>
>>
>
>

--
View this message in context: http://www.nabble.com/TransformedList-question-tp5818064p24227377.html
Sent from the GlazedLists - User mailing list archive at Nabble.com.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@...
For additional commands, e-mail: users-help@...


--------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@... For additional commands, e-mail: users-help@...