FAQ

General

Q: How can I prevent memory leaks with Glazed Lists?

A: Memory leaks can arise when you create short-lived transformations of long-lived EventLists. Because the TransformationLists register themselves as listeners on their source, this reference from their source list may prevent them from being garbage collected. To avoid this problem, use the dispose() method on your TransformationList when you are finished with it.

   // temporary list

   SortedList temporaryList = new SortedList(someLongLivedList);

   ...

   // allows the TransformedList to be garbage collected

   // before its source list is garbage collected

   temporaryList.dispose();

Reference: 2005-01-05

Q: How do I tell Glazed Lists that an Object in my EventList has been updated?

A1: The easiest way to do this currently is to find the index of the updated element and to set() that element as itself. In "normal" Lists, this operation does nothing. But in Glazed Lists, this forces the specified Object to be updated:

   int index = ...

   Object updatedObject = list.get(index);

   list.set(index, updatedObject);

A2: If the elements in your EventList are observable (i.e. some kind of Listener can be used to observe their changes, such as a PropertyChangeListener) then a Glazed Lists pipeline can include an ObservableElementList which will perform the task of notifying the EventList when any of the elements reports a change. Watch the ObservableElementList screencast here for details.

Reference: none

Concurrency

Q: When my EventList changes rapidly, I get RuntimeExceptions

Exception in thread "main" java.lang.NullPointerException

  at ca.odell.glazedlists.event.ListEvent.nextBlock(ListEvent.java:132)

  at ca.odell.glazedlists.swing.EventTableModel.listChanged(EventTableModel.java:117)

  ...

java.lang.IllegalStateException: Cannot commit without an event in progress

  at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:233)

  at ca.odell.glazedlists.impl.gui.ThreadProxyEventList$UpdateRunner.run(ThreadProxyEventList.java:137)

  ...

A: Make sure you're obtaining a lock whenever you access an EventList that is shared between multiple threads. Since Swing starts its own thread it is possible that you're using Glazed Lists concurrently without explicitly planning for it! Adding locking is fairly simple:

   EventList myList = ...

   myList.getReadWriteLock().writeLock().lock();

   try {

      myList.set(...);

      myList.add(...);

      myList.clear();

   }

   finally {

      myList.getReadWriteLock().writeLock().unlock();

   }

Reference: 2005-06-28

Q: Why do I get a ConcurrentModificationException when the user filters while data is being loaded?

A: You need to use read/write locks for the thread that is loading your data. Acquire the lock for this EventList before adding elements. Here's a quick code example:

   EventList myList = ...

   Collection loadedValues = someTimeConsumingMethod();

   myList.getReadWriteLock().writeLock().lock();

   try {

      myList.addAll(loadedValues);

   }

   finally {

       myList.getReadWriteLock().writeLock().unlock();

   }

Reference: 2005-04-07

Filtering

Q: How can I make implementing TextFilterator easier?

A: The TextFilterList has a convenience constructor that uses JavaBeans reflection to make this very easy. Suppose you have a data object with methods the String getMascot(), String getColor(), and String getHomeTown(). Then you can create a TextFilterator easily:

   // property names for getMascot() etc.

   String[] filterProperties = new String[] { "mascot", "color", "homeTown" };

   TextFilterator myFilterator = GlazedLists.textFilterator(filterProperties);

   // create the filter list

   EventList myEventList = ...

   TextFilterList myTextFilterList = new TextFilterList(myEventList, myFilterator);

JLists & JTables

Q: How do I retain selection when my JTable is sorted?

A: Via EventSelectionModel. Create an EventSelectionModel using the same EventList as your EventTableModel. Then install it into your JTable using its setSelectionModel() method.

   EventList eventList = ...

   TableFormat tableFormat = ...

   EventTableModel tableModel = new EventTableModel(eventList, tableFormat);

   EventSelectionModel selectionModel = new EventSelectionModel(eventList);

   JTable table = new JTable(tableModel);

   table.setSelectionModel(selectionModel);

This solution also applies to JList

Reference: 2006-09-24

Q: How do I retain selection when an element is reordered due to a cell edit?

A: Naturally, SortedList shifts elements when their sort order changes, which causes selection to be lost. By configuring your SortedList so that elements are not shifted, selection will not be lost:

   SortedList sorted = ...

   sorted.setMode(SortedList.AVOID_MOVING_ELEMENTS);

Reference: 2006-09-24

Q: How do I set the default sort column on my JTable?

A1: Via the SortedList. Call setComparator() using one of the comparators returned from TableComparatorChooser.getComparatorsForColumn().

A2: Via the TableComparatorChooser. Just call

TableComparatorChooser.chooseComparator().

Reference: 2005-01-13

Q: How can I prevent my JTable from losing its selection when the TableFormat is changed on the underlying EventTableModel?

A: This problem is a limitation of TableModelEvent and JTable. Fortunately there is a simple workaround. You must lock your selection in place before changing the TableFormat by calling:

   EventSelectionModel.setEnabled(false);

After the TableFormat has been changed, you should unlock the selection by calling:

   EventSelectionModel.setEnabled(true);

Reference: none

Q: How can I customize the behaviour of a JTable's header renderer without losing the sort-direction icons?

A1: The simplest solution is to decorate the existing header renderer. Since the TableComparatorChooser will only decorate the class DefaultTableCellRenderer, you must configure your decorater after the TableComparatorChooser has been constructed.

          A2: If decorating the existing header renderer is not possible or desirable there is another mechansim to display the Glazed Lists sort icons. Write your own custom header renderer which implements SortableRenderer.

          It will be given the sort icon from TableComparatorChooser and is expected to place that icon somewhere within the Component that it returns.

Reference: 2004-12-17

Q: Why do the rows in my JTable move after they've been edited?

A: When you have a SortedList, Glazed Lists insists that it stay sorted, even if this has negative consequences. There is an elegant fix in the works that should solve this problem for sorting, filtering and other transformations.

Reference: none

Q: How can I customize which mouse clicks the TableComparatorChooser responds to?

A: You can extend the TableComparatorChooser and override the method isSortingMouseEvent(MouseEvent). This will allow you to set the TableComparatorChooser to handle only right clicks, only left-clicks or even control-clicks. You could even configure your TableComparatorChooser to only handle clicks in a certain application-specific state.

Reference: none

Q: How can I make implementing TableFormat easier?

A: You can implement TableFormat using the same JavaBeans reflection as the TextFilterList. This allows you to create a very basic TableFormat in just three lines of code:

   // property names for getMascot() etc.

   String[] columnProperties = { "mascot", "color", "homeTown" };

   String[] columnLabels = { "Team Mascot", "Color", "Home Town" };

   TableFormat myTableFormat = GlazedLists.tableFormat(columnProperties, columnLabels);

   

   // create the filter list

   EventList myEventList = ...

   EventTableModel myTableModel = new EventTableModel(myEventList, myTableFormat);

Reference: none

Q: How can I make sorting case-insensitive?

A: The easiest way is to change your TableFormat class to implement AdvancedTableFormat as well. This will require two additional methods. Here's a simple implementation that makes columns 3 and 5 ignore capitalization:

class MyTableFormat implements AdvancedTableFormat {

    ......

    public Class getColumnClass(int column) {

        return Object.class;

    }

    public Comparator getColumnComparator(int column) {

         if(column == 3 || column == 5) return GlazedLists.caseInsensitiveComparator();

         else return GlazedLists.comparableComparator();

    }

}

Reference: 2005-04-12

Q: How can I sort a Boolean using TableComparatorChooser and SortedList?

A: You need to use a Comparator that compares Booleans. For your convenience, Glazed Lists includes such a comparator:

   Comparator booleanComparator = GlazedLists.booleanComparator(); 

You still need to apply the Comparator to the appropriate column of your table. The TableComparatorChooser.createComparatorForElement() method is handy for this because it creates a comparator for your list elements from a comparator of column values:

   int booleanColumn = ...

   TableComparatorChooser tcc = ...

   Comparator booleanComparator = GlazedLists.booleanComparator();

   Comparator elementComparator = tcc.createComparatorForElement(booleanComparator, booleanColumn);

   List booleanComparators = tcc.getComparatorsForColumn(booleanColumn);

   booleanComparators.clear();

   booleanComparators.add(elementComparator);

Reference: 2004-11-15

Q: I am using TableComparatorChooser. How do I sort by true date rather than alphabetically?

A: You'll need to return Date objects from your TableFormat's getColumnValue() method. It will compare the Dates in the canonical way. :One problem you may face with returning Dates is that they may show up in your table as the rather ugly toString() value returned by that class. To overcome this, use a TableCellRenderer that pretty prints your date such as DateTableCellRenderer from renderpack.

Reference: 2004-10-06

Q: How do I get my JTable or JList to retain its selection when it is sorted?

A: You need to specify that your JTable or JList use an EventSelectionModel, which is sorting-aware:

   EventList myList = ...

   EventTableModel myTableModel = new EventTableModel(myList, ...);

   JTable myTable = new JTable(myTableModel);

   EventSelectionModel myEventSelectionModel = new EventSelectionModel(myList);

   myTable.setSelectionModel(myEventSelectionModel);

Reference: none

Q: I have a JButton within a table cell. Why doesn't it receive click events?

A: First off, your JButton must have both a TableCellRenderer for fast-painting and a TableCellEditor for interaction. By default, EventTableModel will always use the TableCellRenderer and your TableCellEditor will go unused. To tell EventTableModel to use your editor, implement the WritableTableFormat interface instead of the TableFormat interface. It has additional methods for specifying which columns are editable and how to respond to edit events.

Reference: none

Q: How do I specify that my boolean table cells be rendered with a checkbox? For some reason, Glazed Lists has no getColumnClass() method.

A: If you need to specify the column class, you need to implement the AdvancedTableFormat interface instead of the regular TableFormat class.

If you are using the GlazedLists.tableFormat() factory method, you must specify the base Object's class for a proper implementation of the AdvancedTableFormat.getColumnClass() method.

Reference: 2004-12-01

Q: How do I configure my table's column to sort with multiple Comparators? I can't find it in AdvancedTableFormat.

A: You can only specify one Comparator using the AdvancedTableFormat. If you need to use multiple Comparators, you must use the TableComparatorChooser's getComparatorsForColumn() method:

   TableComparatorChooser tableSorter = TableComparatorChooser.install(table, sortedList, AbstractTableComparatorChooser.MULTIPLE_COLUMN_MOUSE);

   Comparator caseInsensitiveComparator = GlazedLists.caseInsensitiveComparator();

   Comparator column5CaseInsensitiveComparator = tableSorter.createComparatorForElement(caseInsensitiveComparator, 5);

   tableSorter.getComparatorsForColumn(5).add(column5CaseInsensitiveComparator);

Reference: 2005-03-31

API

Q: Why isn't there Javadoc for the impl package?

A: The impl package is reserved for classes that support the other Glazed Lists packages. This "non-public" package should be considered similar to Java's com.sun packages. We reserve the right to change the classes in this package so it is best to avoid using them directly.

Fortunately there's a factory class to help you get at the best of the impl package without importing it. The GlazedLists class is a factory class not unlike the Java Collections Framework's Collections factory class. It can be used to provide natural implementations of common Glazed Lists interfaces: EventList, TextFilterator, TableFormat and even Comparator.

Reference: 2005-07-08

Q: Why is the BasicEventList(List) constructor deprecated?

A: With that constructor, it is possible for the backing store List to change out from under the EventList that uses it. This can lead to an EventList that is in an inconsistent state, a very undesirable situation.

When it is necessary to keep a regular List in sync with an EventList, you can use the GlazedLists.syncEventListToList() utility method. This creates a ListEventListener that updates a List whenever its peer EventList is changed.

Reference: 2005-06-16

Performance

Q: My SortedList performs badly, e.g. when I add a lot of elements. What's the cause of this?

A: Please check your runtime environment, if you have assertions enabled. Some of the Glazed Lists assertions used internally could cause a performance degradation. Try to disable the Glazed Lists assertions by using the following options -ea -da:ca.odell.glazedlists...

more on assertions

Reference: 2007-07-04

Other Problems

Q: I think I've discovered a bug in Glazed Lists! What should I do now?

A: If you're using an older version of Glazed Lists, upgrade to the latest release! We're continuously fixing bugs plus the new releases offer a simpler API and more features.

To get a list of critical bugs opened since your version was released, click on the appropriate link to visit our issue tracker.

To submit a bug, join the project as an Observer and go to our handy bug submission form. We will address the bug immediately and give you a timeline on when to expect a fix.

Reference: 2005-03-31

Q: My question is not answered here. What do I do now?

A: A quick search on the mailing list archive may solve some problems. Otherwise send questions to users@glazedlists.dev.java.net.

Reference: none