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
EventList
s. Because the TransformationList
s
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" List
s, 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 RuntimeException
s
-
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 Boolean
s. 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 Date
s in the canonical way. :One problem you may face with returning Date
s 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
Comparator
s? I can't find it in AdvancedTableFormat
.
- A: You can only specify one
Comparator
using the AdvancedTableFormat
. If you need to use multiple Comparator
s, 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