javamvvmglazedlistspluggablebeans-binding

How to deal with GlazedLists's PluggableList requirement for shared publisher and lock


I have just started using GlazedLists in a Java project which uses beansbinding extensively (MVVM pattern).

PluggableList is allowing me to bind a source list to a table, and then change the source list at runtime. In order to make this happen every source list must share the same ListEventPublisher and ReadWriteLock, since PluggableList must share a lock and plublisher with it's source. I accomplish this by creating a static publisher and lock in my class that owns the potential source lists, use those static values to create the list in every instantiation of the class as well as the PluggableList, as shown in the pseudo code below:

public class ModelClass
{
    final static EventList          LIST               = new BasicEventList();
    final static ListEventPublisher LISTEVENTPUBLISHER = LIST.getPublisher();
    final static ReadWriteLock      READWRITELOCK      = LIST.getReadWriteLock();

    final EventList                 sourceList         = 
            new BasicEventList(LISTEVENTPUBLISHER, READWRITELOCK);
}


public class UiControllerClass
{
    final PluggableList pluggableList = 
        new PluggableList(ModelClass.LISTEVENTPUBLISHER, ModelClass.READWRITELOCK);

    // ... call pluggableList.setSource(someSourceList) 
}

I have two concerns with this:

(1) I have to make a decision in the Model because of a specific requirement of a component in the UiController. This seems to violate the MVVM pattern.

(2) The shared lock potentially impacts the performance of the lists if there are very many and they are accessed frequently, since they all share the same lock. Each of these lists should otherwise be able to operate independently without caring about each other.

Am I going about this incorrectly? Is there a better way to make PluggableLists work without the ModelClass having to know about a special UiControllerClass requirement and without the potential performance hit?


Solution

  • I came up with an elegant solution that preserves the MVVM pattern as well as eliminates the need for a shared lock and publisher.

    I created a custom list transformation that extends PluggableList and overrides it's setSource method. The new source list is then synchronized with a new list created by the PluggableList (it will have the same publisher and lock as the PluggableList).

    public class HotSwappablePluggableList<T>
            extends PluggableList<T>
    {
        private EventList<T>         syncSourceList    = new BasicEventList<>();
        private ListEventListener<T> listEventListener = null;
    
        public HotSwappablePluggableList()
        {
            super(new BasicEventList<T>());
        }
    
        @Override
        public void setSource(final EventList<T> sourceList)
        {
            getReadWriteLock().writeLock().lock();
            try
            {
                if (listEventListener != null)
                {
                    syncSourceList.removeListEventListener(listEventListener);
                }
    
                syncSourceList = sourceList;
    
                final EventList<T> syncTargetList = createSourceList();
                listEventListener = GlazedLists.syncEventListToList(syncSourceList, syncTargetList);
    
                super.setSource(syncTargetList);
            }
            finally
            {
                getReadWriteLock().writeLock().unlock();
            }
        }
    }