![JAR search and dependency download from the Maven repository](/logo.png)
ca.odell.glazedlists.swing.EventTableModel Maven / Gradle / Ivy
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.swing;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TransformedList;
import ca.odell.glazedlists.gui.TableFormat;
import javax.swing.SwingUtilities;
import javax.swing.table.TableModel;
/**
* A {@link DefaultEventTableModel} that silently wraps it's source list in a
* SwingThreadProxyEventList to ensure that events that arrive at the TableModel do so on
* the EDT. A {@link TableModel} that holds an {@link EventList}. Each element of the list
* corresponds to a row in the {@link TableModel}. The columns of the table are specified using a
* {@link TableFormat}.
*
* The EventTableModel class is not thread-safe. Unless otherwise noted, all
* methods are only safe to be called from the event dispatch thread. To do this
* programmatically, use {@link SwingUtilities#invokeAndWait(Runnable)}.
*
* @see Glazed Lists Tutorial
* @see SwingUtilities#invokeAndWait(Runnable)
* @see Bug 112
* @see Bug 146
* @see Bug 177
*
* @deprecated Use {@link DefaultEventTableModel} instead. This class will be removed in the GL
* 2.0 release. The wrapping of the source list with an EDT safe list has been
* determined to be undesirable (it is better for the user to provide their own EDT
* safe list).
*
* @author Jesse Wilson
*/
@Deprecated
public class EventTableModel extends DefaultEventTableModel {
/** the proxy moves events to the Swing Event Dispatch thread */
protected TransformedList swingThreadSource;
/**
* Creates a new table model that extracts column data from the given source
* using the the given tableFormat
.
*
* @param source the EventList that provides the row objects
* @param tableFormat the object responsible for extracting column data from the row objects
*
* @deprecated Use {@link DefaultEventTableModel} and
* {@link GlazedListsSwing#swingThreadProxyList(EventList)} instead
*/
@Deprecated
public EventTableModel(EventList source, TableFormat super E> tableFormat) {
super(source, tableFormat);
// lock the source list for reading since we want to prevent writes
// from occurring until we fully initialize this EventTableModel
// KD 20090306 - Not crazy about these locks, but it was in the original
// EventTableModel implementation, so we need to leave it. DefaultTableModel
// should be considered to be non-Thread Safe, so source lists should be locked
// before constructing a DefaultEventTableModel if there are any potential
// race conditions
source.getReadWriteLock().readLock().lock();
try {
final TransformedList decorated = createSwingThreadProxyList(source);
if (decorated != null && decorated != source){
//we need to switch the configuration of the DefaultEventTableModel so it
// uses the swingThreadProxyList instead
this.source.removeListEventListener(this);
this.source = swingThreadSource = decorated;
this.source.addListEventListener(this);
}
} finally {
source.getReadWriteLock().readLock().unlock();
}
}
/**
* Creates a new table that renders the specified list with an automatically
* generated {@link TableFormat}. It uses JavaBeans and reflection to create
* a {@link TableFormat} as specified.
*
* Note that the classes which will be obfuscated may not work with
* reflection. In this case, implement a {@link TableFormat} manually.
*
* @param source the EventList that provides the row objects
* @param propertyNames an array of property names in the JavaBeans format.
* For example, if your list contains Objects with the methods getFirstName(),
* setFirstName(String), getAge(), setAge(Integer), then this array should
* contain the two strings "firstName" and "age". This format is specified
* by the JavaBeans {@link java.beans.PropertyDescriptor}.
* @param columnLabels the corresponding column names for the listed property
* names. For example, if your columns are "firstName" and "age", then
* your labels might be "First Name" and "Age".
* @param writable an array of booleans specifying which of the columns in
* your table are writable.
*
* @deprecated Use {@link GlazedListsSwing#eventTableModel(EventList, String[], String[], boolean[])}
* and {@link GlazedListsSwing#swingThreadProxyList(EventList)} instead
*/
@Deprecated
public EventTableModel(EventList source, String[] propertyNames, String[] columnLabels, boolean[] writable) {
this(source, GlazedLists.tableFormat(propertyNames, columnLabels, writable));
}
/**
* This method exists as a hook for subclasses that may have custom
* threading needs within their EventTableModels. By default, this method
* will wrap the given source
in a SwingThreadProxyList if it
* is not already a SwingThreadProxyList. Subclasses may replace this logic
* and return either a custom ThreadProxyEventList of their choosing, or
* return null
or the source
unchanged in order
* to indicate that NO ThreadProxyEventList is desired.
* In these cases it is expected that some external mechanism will ensure
* that threading is handled correctly.
*
* @param source the EventList that provides the row objects
* @return the source wrapped in some sort of ThreadProxyEventList if
* Thread-proxying is desired, or either null
or the
* source
unchanged to indicate that NO
* Thread-proxying is desired
*/
protected TransformedList createSwingThreadProxyList(EventList source) {
return GlazedListsSwing.isSwingThreadProxyList(source) ? null : GlazedListsSwing.swingThreadProxyList(source);
}
/**
* Releases the resources consumed by this {@link EventTableModel} so that it
* may eventually be garbage collected.
*
* An {@link EventTableModel} will be garbage collected without a call to
* {@link #dispose()}, but not before its source {@link EventList} is garbage
* collected. By calling {@link #dispose()}, you allow the {@link EventTableModel}
* to be garbage collected before its source {@link EventList}. This is
* necessary for situations where an {@link EventTableModel} is short-lived but
* its source {@link EventList} is long-lived.
*
*
Warning: It is an error
* to call any method on an {@link EventTableModel} after it has been disposed.
* As such, this {@link EventTableModel} should be detached from its
* corresponding Component before it is disposed.
*/
@Override
public void dispose() {
// if we created the swingThreadSource then we must also dispose it
if (swingThreadSource != null) {
swingThreadSource.dispose();
}
swingThreadSource = null;
super.dispose();
}
}