Initial commit from SVN.
This commit is contained in:
@@ -0,0 +1,860 @@
|
||||
/*
|
||||
* Copyright (c) 2004,2009 Declarative Engineering LLC.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Declarative Engineering LLC
|
||||
* verson 1 which accompanies this distribution, and is available at
|
||||
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
|
||||
*/
|
||||
package com.foundation.tcv.swt.server;
|
||||
|
||||
import com.common.comparison.Comparator;
|
||||
import com.common.util.*;
|
||||
import com.common.util.optimized.IntArray;
|
||||
import com.foundation.metadata.Attribute;
|
||||
import com.foundation.tcv.swt.ITableComponent;
|
||||
import com.foundation.tcv.view.IAbstractRemoteViewComponent;
|
||||
import com.foundation.tcv.view.ViewMessage;
|
||||
import com.foundation.view.*;
|
||||
import com.foundation.view.resource.ResourceReference;
|
||||
|
||||
/*
|
||||
* The simple table is a very simple implementation of a basic table.
|
||||
* Initialy this contains just text with no extra formatting using the native table component.
|
||||
*/
|
||||
public abstract class TableComponent extends CollectionComponent implements ITableComponent {
|
||||
/** The font resource for the control rows. (Note: This overrides the base font for the control defined by the Component class.) */
|
||||
private MultiResourceAssociation rowFont = new MultiResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_FONT, false, null);
|
||||
/** The background color resource for the control. */
|
||||
private MultiResourceAssociation rowBackgroundColorCustom = new MultiResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The foreground color resource for the control. */
|
||||
private MultiResourceAssociation rowForegroundColorCustom = new MultiResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The background color resource for the control. */
|
||||
private SingleResourceAssociation rowBackgroundColor = new SingleResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The foreground color resource for the control. */
|
||||
private SingleResourceAssociation rowForegroundColor = new SingleResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The background color resource for the control. */
|
||||
private SingleResourceAssociation rowBackgroundColorAlt = new SingleResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The foreground color resource for the control. */
|
||||
private SingleResourceAssociation rowForegroundColorAlt = new SingleResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_COLOR, false, null);
|
||||
/** The selection color resource for the control. */
|
||||
private VariableResourceAssociation rowSelectionGradient = new VariableResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_GRADIENT, false, null);
|
||||
/** The row height used. */
|
||||
private SingleResourceAssociation rowHeight = new SingleResourceAssociation(this, this, getViewContext(), ResourceAssociation.TYPE_INTEGER, false, null);
|
||||
/** The collection of columns in order of appearance (left to right). */
|
||||
private IList tableColumns = new LiteList(16);
|
||||
/** Tracks whether or not to try updating the selection if the collection changed. */
|
||||
private boolean isSelectionInvalid = false;
|
||||
/** The mapping of image decoration data by the decoration object. This is used to improve efficiency when placing a decoration on multiple rows. */
|
||||
protected IHashMap decorationDataMap = null;
|
||||
/** The last used decoration data identifier. The identifier is used to tell the client which decoration is being talked about. */
|
||||
private int nextDecorationDataId = 0;
|
||||
|
||||
/**
|
||||
* Maintains the reference counter and ID for each decoration in the decoration data map. Also allows a decoration to be shared by multiple rows.
|
||||
*/
|
||||
protected class DecorationData {
|
||||
/** The data identifier used to notify the client about this decoration's change in status. */
|
||||
private int decorationId = nextDecorationDataId++;
|
||||
/** The number of times the data is being referenced (by rows displaying it). */
|
||||
private int referenceCount = 1;
|
||||
|
||||
/**
|
||||
* DecorationData constructor.
|
||||
* @param decoration The decoration this data object supports.
|
||||
*/
|
||||
public DecorationData(ImageDecoration decoration) {
|
||||
}//DecorationData()//
|
||||
/**
|
||||
* Increments the reference counter for the decoration.
|
||||
*/
|
||||
public void incrementReferenceCount() {
|
||||
referenceCount++;
|
||||
}//incrementReferenceCount()//
|
||||
/**
|
||||
* Decrements the reference counter for the decoration.
|
||||
* @return The reference count for the decoration data.
|
||||
*/
|
||||
public int decrementReferenceCount() {
|
||||
return --referenceCount;
|
||||
}//decrementReferenceCount()//
|
||||
}//DecorationData//
|
||||
|
||||
/**
|
||||
* Encapsulates all the data pertaining to a single column in the table component.
|
||||
*/
|
||||
public static abstract class AbstractColumn implements IAbstractComponent, IAbstractRemoteViewComponent {
|
||||
/**
|
||||
* Registers an item in the collection with this column.
|
||||
* <p>An item can be registered more than once, but must be unregistered just as many times.</p>
|
||||
* @param rowObject The row to be registered.
|
||||
*/
|
||||
protected void registerItem(RowObject rowObject) {
|
||||
}//registerItem()//
|
||||
/**
|
||||
* Unregisters an item that had been previously registered.
|
||||
* @param rowObject The row to be unregistered.
|
||||
*/
|
||||
protected void unregisterItem(RowObject rowObject) {
|
||||
}//unregisterItem()//
|
||||
/**
|
||||
* Unregisters all items that had been previously registered.
|
||||
*/
|
||||
protected void unregisterAllItems() {
|
||||
}//unregisterAllItems()//
|
||||
/**
|
||||
* Refreshes the value for the cell(s) denoted by the item representing the row(s) and this column.
|
||||
* @param rowObject The row data containing the row's value and metadata.
|
||||
* @return Whether the cell data was altered by the refresh.
|
||||
*/
|
||||
protected abstract boolean refreshCellData(RowObject rowObject);
|
||||
/**
|
||||
* Collects the cell data for the given row and this column.
|
||||
* @param rowObject The row data containing the row's value and metadata.
|
||||
* @param cellData The table cell data structure to be filled in.
|
||||
*/
|
||||
protected void collectCellData(RowObject rowObject, TableCellData cellData) {
|
||||
}//collectCellData()//
|
||||
/**
|
||||
* Gets the column's creation index.
|
||||
* @return The index assigned to this column and used to facilitate communication with the actual column resource in the display.
|
||||
*/
|
||||
protected abstract int getIndex();
|
||||
/**
|
||||
* Sets the column's creation index.
|
||||
* @param index The index assigned to this column and used to facilitate communication with the actual column resource in the display.
|
||||
*/
|
||||
protected abstract void setIndex(int index);
|
||||
/**
|
||||
* Initializes the column before the table component is initialized.
|
||||
*/
|
||||
protected abstract void initialize();
|
||||
/**
|
||||
* Refreshes the column.
|
||||
*/
|
||||
protected abstract void refresh();
|
||||
/**
|
||||
* Releases the column before the table component is released.
|
||||
*/
|
||||
protected abstract void release();
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IAbstractViewComponent#processMessage(com.foundation.tcv.view.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
return null;
|
||||
}//processMessage()//
|
||||
}//AbstractColumn//
|
||||
/**
|
||||
* TableComponent constructor.
|
||||
* @param parent The parent container for this component.
|
||||
* @param name The name of the component.
|
||||
*/
|
||||
public TableComponent(Container parent, String name, int style) {
|
||||
super(parent, name, style);
|
||||
}//TableComponent()//
|
||||
/**
|
||||
* Adds a column to the component.
|
||||
* @param column The column to be added.
|
||||
*/
|
||||
protected void addColumn(AbstractColumn column) {
|
||||
if(isInitialized()) {
|
||||
//Allow the collection to suspend activites that would adversly affect performance while the collection make large scale changes.//
|
||||
preChangeCollection();
|
||||
}//if//
|
||||
|
||||
try {
|
||||
tableColumns.add(column.getIndex(), column);
|
||||
|
||||
//Update the other column indices.//
|
||||
for(int index = column.getIndex() + 1; index < tableColumns.getSize(); index++) {
|
||||
((AbstractColumn) tableColumns.get(index)).setIndex(index);
|
||||
}//for//
|
||||
|
||||
//Notify the client.//
|
||||
sendMessage(MESSAGE_ADD_COLUMN, new Integer(column.getIndex()));
|
||||
}//try//
|
||||
finally {
|
||||
if(isInitialized()) {
|
||||
//Allow the table to refresh its self.//
|
||||
postChangeCollection();
|
||||
}//if//
|
||||
}//finally//
|
||||
}//addColumn()//
|
||||
/**
|
||||
* Gets the number of columns in the table.
|
||||
* @return The count of columns.
|
||||
*/
|
||||
protected int getColumnCount() {
|
||||
return tableColumns.getSize();
|
||||
}//getColumnCount()//
|
||||
/**
|
||||
* Gets the column at the given index.
|
||||
* @param index The zero based column index.
|
||||
* @return The column at the given index.
|
||||
*/
|
||||
protected AbstractColumn getColumn(int index) {
|
||||
return (AbstractColumn) tableColumns.get(index);
|
||||
}//getColumn()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshCollection(com.common.util.ICollection, com.common.util.ICollection)
|
||||
*/
|
||||
protected void internalViewRefreshCollection(ICollection newCollection, ICollection oldCollection) {
|
||||
itemAllRemoved();
|
||||
|
||||
if(newCollection != null) {
|
||||
// TableRowData[] data = new TableRowData[newCollection.getSize()];
|
||||
// Object[] hiddenData = new Object[newCollection.getSize()];
|
||||
IIterator itemIterator = newCollection.iterator();
|
||||
int itemIndex = 0;
|
||||
|
||||
//Get the array of strings representing the list contents.//
|
||||
while(itemIterator.hasNext()) {
|
||||
Object item = itemIterator.next();
|
||||
|
||||
itemAdded(item, itemIndex++, true);
|
||||
|
||||
// RowObject rowObject = itemAdded(value, index, false);
|
||||
//
|
||||
// //Add the item mappings without notifying the client.//
|
||||
// if(rowObject.isFirstReference()) {
|
||||
// data[itemIndex] = new TableRowData(getRowObject(item).objectId, itemIndex, null, null);
|
||||
// hiddenData[itemIndex] = getItemHiddenData(item);
|
||||
// }//if//
|
||||
// else {
|
||||
// data[itemIndex] = new TableRowData(getRowObject(item).objectId, itemIndex, getItemData(rowObject));
|
||||
// hiddenData[itemIndex] = null;
|
||||
// }//else//
|
||||
}//while//
|
||||
|
||||
//TODO: It would probably be more efficient to send many small messages and allow the sending code to take care of bundling to the optimum size.
|
||||
//addMessageHold(); Use this to block message sending until finished? May not need it since the messages should bundle up anyway.
|
||||
// sendMessage(MESSAGE_SET_ITEMS, data, hiddenData, -1, -1);
|
||||
}//if//
|
||||
|
||||
//If the selection was invalid previously then refresh the selection since it may no longer be invalid.//
|
||||
if(isSelectionInvalid) {
|
||||
internalViewRefreshSelection();
|
||||
}//if//
|
||||
}//internalViewRefreshCollection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#getItemData(com.foundation.tcv.swt.server.RowObject)
|
||||
*/
|
||||
protected Object getItemData(RowObject rowObject) {
|
||||
TableRowData rowData = createTableRowData();
|
||||
TableCellData[] cellDatas = rowData.getColumnData();
|
||||
|
||||
collectRowData(rowObject, rowData);
|
||||
|
||||
for(int index = 0; index < cellDatas.length; index++) {
|
||||
AbstractColumn column = (AbstractColumn) tableColumns.get(index);
|
||||
|
||||
if(column != null) {
|
||||
column.refreshCellData(rowObject);
|
||||
cellDatas[index] = createTableCellData();
|
||||
column.collectCellData(rowObject, cellDatas[index]);
|
||||
}//if//
|
||||
}//for//
|
||||
|
||||
return rowData;
|
||||
}//getItemData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshSelection(java.lang.Object)
|
||||
*/
|
||||
protected void internalViewRefreshSelection(Object selectedItem) {
|
||||
if(selectedItem != null) {
|
||||
RowObject rowObject = (RowObject) getRowObject(selectedItem);
|
||||
|
||||
if(rowObject == null) {
|
||||
isSelectionInvalid = true;
|
||||
sendMessage(MESSAGE_SET_SELECTION, null);
|
||||
}//if//
|
||||
else {
|
||||
isSelectionInvalid = false;
|
||||
sendMessage(MESSAGE_SET_SELECTION, new int[] {rowObject.objectId});
|
||||
}//else//
|
||||
}//if//
|
||||
else {
|
||||
//No selection.//
|
||||
sendMessage(MESSAGE_SET_SELECTION, null);
|
||||
}//else//
|
||||
}//internalViewRefreshSelection()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefreshSelections(com.common.util.ICollection, com.common.util.ICollection)
|
||||
*/
|
||||
protected void internalViewRefreshSelections(ICollection newSelections, ICollection oldSelections) {
|
||||
if(newSelections != null) {
|
||||
IntArray selectionObjectIds = new IntArray(newSelections.getSize());
|
||||
IIterator selectionIterator = newSelections.iterator();
|
||||
|
||||
//Apply differences between the selection collection and the control selection. Also remove all impossible selections.//
|
||||
while(selectionIterator.hasNext()) {
|
||||
Object selection = selectionIterator.next();
|
||||
RowObject rowObject = (RowObject) getRowObject(selection);
|
||||
|
||||
if(rowObject == null) {
|
||||
//An invalid selection because the selection is not in the collection of displayed values.//
|
||||
selectionIterator.remove();
|
||||
}//if//
|
||||
else {
|
||||
selectionObjectIds.add(rowObject.objectId);
|
||||
}//else//
|
||||
}//while//
|
||||
|
||||
sendMessage(MESSAGE_SET_SELECTION, selectionObjectIds.toArray());
|
||||
}//if//
|
||||
else {
|
||||
//Remove all selections.//
|
||||
sendMessage(MESSAGE_REMOVE_ALL_SELECTIONS, null);
|
||||
}//else//
|
||||
}//internalViewRefreshSelections()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewInitialize()
|
||||
*/
|
||||
protected void internalViewInitialize() {
|
||||
rowBackgroundColor.initialize();
|
||||
rowForegroundColor.initialize();
|
||||
rowBackgroundColorAlt.initialize();
|
||||
rowForegroundColorAlt.initialize();
|
||||
rowSelectionGradient.initialize();
|
||||
rowBackgroundColorCustom.initialize();
|
||||
rowForegroundColorCustom.initialize();
|
||||
rowFont.initialize();
|
||||
rowHeight.initialize();
|
||||
|
||||
//Initialize all the columns.//
|
||||
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
|
||||
((AbstractColumn) tableColumns.get(columnIndex)).initialize();
|
||||
}//for//
|
||||
|
||||
super.internalViewInitialize();
|
||||
}//internalViewInitialize()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalViewRefresh()
|
||||
*/
|
||||
protected void internalViewRefresh() {
|
||||
sendMessage(MESSAGE_SUSPEND_ROW_COLOR_UPDATES, null, null, -1, -1);
|
||||
internalViewRefreshRowHeight();
|
||||
|
||||
if(rowSelectionGradient.isSingle() && rowSelectionGradient.refresh(null)) {
|
||||
sendMessage(MESSAGE_SET_ROW_SELECTION_GRADIENT, rowSelectionGradient.getValue(null), null, -1, -1);
|
||||
}//if//
|
||||
|
||||
if(rowBackgroundColor.refresh()) {
|
||||
sendMessage(MESSAGE_SET_ROW_BACKGROUND_COLOR, rowBackgroundColor.getValue(), null, -1, -1);
|
||||
}//if//
|
||||
|
||||
if(rowForegroundColor.refresh()) {
|
||||
sendMessage(MESSAGE_SET_ROW_FOREGROUND_COLOR, rowForegroundColor.getValue(), null, -1, -1);
|
||||
}//if//
|
||||
|
||||
if(rowBackgroundColorAlt.refresh()) {
|
||||
sendMessage(MESSAGE_SET_ROW_BACKGROUND_COLOR_ALT, rowBackgroundColorAlt.getValue(), null, -1, -1);
|
||||
}//if//
|
||||
|
||||
if(rowForegroundColorAlt.refresh()) {
|
||||
sendMessage(MESSAGE_SET_ROW_FOREGROUND_COLOR_ALT, rowForegroundColorAlt.getValue(), null, -1, -1);
|
||||
}//if//
|
||||
|
||||
sendMessage(MESSAGE_RESUME_ROW_COLOR_UPDATES, null, null, -1, -1);
|
||||
|
||||
super.internalViewRefresh();
|
||||
|
||||
//Refresh all the columns.//
|
||||
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
|
||||
((AbstractColumn) tableColumns.get(columnIndex)).refresh();
|
||||
}//for//
|
||||
}//internalViewRefresh()//
|
||||
/**
|
||||
* Refreshes the component's row height.
|
||||
*/
|
||||
protected void internalViewRefreshRowHeight() {
|
||||
if(rowHeight.refresh()) {
|
||||
Integer height = (Integer) rowHeight.getValue();
|
||||
|
||||
//Reset to the default height if null but was previously non-null.//
|
||||
sendMessage(MESSAGE_SET_ROW_HEIGHT, height, null, -1, -1);
|
||||
}//if//
|
||||
}//internalViewRefreshRowHeight()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.view.swt.AbstractComponent#internalViewRelease()
|
||||
*/
|
||||
protected void internalViewRelease() {
|
||||
//Release all the columns.//
|
||||
for(int columnIndex = 0; columnIndex < tableColumns.getSize(); columnIndex++) {
|
||||
((AbstractColumn) tableColumns.get(columnIndex)).release();
|
||||
}//for//
|
||||
|
||||
rowBackgroundColor.release();
|
||||
rowForegroundColor.release();
|
||||
rowBackgroundColorAlt.release();
|
||||
rowForegroundColorAlt.release();
|
||||
rowSelectionGradient.release();
|
||||
rowBackgroundColorCustom.release();
|
||||
rowForegroundColorCustom.release();
|
||||
rowFont.release();
|
||||
rowHeight.release();
|
||||
|
||||
super.internalViewRelease();
|
||||
}//internalViewRelease()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.AbstractComponent#internalOnValueChanged(com.foundation.view.MultiResourceAssociation, java.lang.Object, java.lang.Object, boolean)
|
||||
*/
|
||||
protected void internalOnValueChanged(MultiResourceAssociation resourceAssociation, Object item, Object data, boolean isUpdate) {
|
||||
if(isInitialized()) {
|
||||
if(resourceAssociation == rowBackgroundColorCustom) {
|
||||
//Verify that the item cell data has actually been altered.//
|
||||
if(rowBackgroundColorCustom.refresh(item)) {
|
||||
sendMessage(MESSAGE_SET_ROW_CUSTOM_BACKGROUND_COLOR, rowBackgroundColorCustom.getValue(item), null, -1, -1);
|
||||
}//if//
|
||||
}//if//
|
||||
else if(resourceAssociation == rowForegroundColorCustom) {
|
||||
//Verify that the item cell data has actually been altered.//
|
||||
if(rowForegroundColorCustom.refresh(item)) {
|
||||
sendMessage(MESSAGE_SET_ROW_CUSTOM_FOREGROUND_COLOR, rowForegroundColorCustom.getValue(item), null, -1, -1);
|
||||
}//if//
|
||||
}//else if//
|
||||
else if(rowSelectionGradient.hasAssociation(resourceAssociation)) {
|
||||
//Verify that the item cell data has actually been altered.//
|
||||
if(rowSelectionGradient.refresh(item)) {
|
||||
sendMessage(MESSAGE_SET_ROW_SELECTION_GRADIENT, rowSelectionGradient.getValue(item), null, -1, -1);
|
||||
}//if//
|
||||
}//else if//
|
||||
else if(resourceAssociation == rowFont) {
|
||||
//Verify that the item cell data has actually been altered.//
|
||||
if(rowFont.refresh(item)) {
|
||||
sendMessage(MESSAGE_SET_ROW_FONT, rowFont.getValue(item), null, -1, -1);
|
||||
}//if//
|
||||
}//else if//
|
||||
else {
|
||||
super.internalOnValueChanged(resourceAssociation, item, data, isUpdate);
|
||||
}//else//
|
||||
}//if//
|
||||
}//internalOnValueChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#internalOnValueChanged(com.foundation.view.SingleResourceAssociation, boolean)
|
||||
*/
|
||||
protected void internalOnValueChanged(SingleResourceAssociation resourceAssociation, int flags) {
|
||||
if(isInitialized()) {
|
||||
if(resourceAssociation == rowHeight) {
|
||||
sendMessage(MESSAGE_SET_ROW_HEIGHT, rowHeight.getValue(), null, -1, -1);
|
||||
}//if//
|
||||
else if(resourceAssociation == rowBackgroundColor) {
|
||||
sendMessage(MESSAGE_SET_ROW_BACKGROUND_COLOR, rowBackgroundColor.getValue(), null, -1, -1);
|
||||
}//else if//
|
||||
else if(resourceAssociation == rowForegroundColor) {
|
||||
sendMessage(MESSAGE_SET_ROW_FOREGROUND_COLOR, rowForegroundColor.getValue(), null, -1, -1);
|
||||
}//else if//
|
||||
else if(resourceAssociation == rowBackgroundColorAlt) {
|
||||
sendMessage(MESSAGE_SET_ROW_BACKGROUND_COLOR_ALT, rowBackgroundColorAlt.getValue(), null, -1, -1);
|
||||
}//else if//
|
||||
else if(resourceAssociation == rowForegroundColorAlt) {
|
||||
sendMessage(MESSAGE_SET_ROW_FOREGROUND_COLOR_ALT, rowForegroundColorAlt.getValue(), null, -1, -1);
|
||||
}//else if//
|
||||
else {
|
||||
super.internalOnValueChanged(resourceAssociation, flags);
|
||||
}//else//
|
||||
}//if//
|
||||
}//internalOnValueChanged()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#itemSorted(int[])
|
||||
*/
|
||||
protected void itemSorted(int[] mapping) {
|
||||
sendMessage(MESSAGE_ORDER_ROWS, mapping);
|
||||
}//itemSorted()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionAdded(java.lang.Object)
|
||||
*/
|
||||
protected void selectionAdded(Object value) {
|
||||
RowObject rowObject = getRowObject(value);
|
||||
|
||||
if(rowObject != null) {
|
||||
sendMessage(MESSAGE_ADD_SELECTION, null, null, rowObject.objectId, -1);
|
||||
}//if//
|
||||
}//selectionAdded()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionRemoved(java.lang.Object)
|
||||
*/
|
||||
protected void selectionRemoved(Object value) {
|
||||
RowObject rowObject = getRowObject(value);
|
||||
|
||||
if(rowObject != null) {
|
||||
sendMessage(MESSAGE_REMOVE_SELECTION, null, null, rowObject.objectId, -1);
|
||||
}//if//
|
||||
}//selectionRemoved()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#selectionAllRemoved()
|
||||
*/
|
||||
protected void selectionAllRemoved() {
|
||||
sendMessage(MESSAGE_REMOVE_ALL_SELECTIONS, null);
|
||||
}//selectionAllRemoved()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#registerItem(com.foundation.tcv.swt.server.RowObject)
|
||||
*/
|
||||
protected void registerItem(RowObject rowObject) {
|
||||
super.registerItem(rowObject);
|
||||
|
||||
//Add the item to each of the columns so we receive updates.//
|
||||
for(int index = 0; index < tableColumns.getSize(); index++) {
|
||||
((AbstractColumn) tableColumns.get(index)).registerItem(rowObject);
|
||||
}//for//
|
||||
}//registerItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItem(com.foundation.tcv.swt.server.RowObject)
|
||||
*/
|
||||
protected void unregisterItem(RowObject rowObject) {
|
||||
super.unregisterItem(rowObject);
|
||||
|
||||
//Unregister the value with the columns so we stop receiving updates.//
|
||||
for(int index = 0; index < tableColumns.getSize(); index++) {
|
||||
((AbstractColumn) tableColumns.get(index)).unregisterItem(rowObject);
|
||||
}//for//
|
||||
}//unregisterItem()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.swt.server.CollectionComponent#unregisterItems()
|
||||
*/
|
||||
protected void unregisterItems() {
|
||||
super.unregisterItems();
|
||||
|
||||
//Unregister the items from the columns so we stop recieving updates.//
|
||||
for(int index = 0; index < tableColumns.getSize(); index++) {
|
||||
((AbstractColumn) tableColumns.get(index)).unregisterAllItems();
|
||||
}//for//
|
||||
}//unregisterItems()//
|
||||
/**
|
||||
* Collects the data for the given row item.
|
||||
* @param rowObject The row data containing the row's value and metadata.
|
||||
* @param rowData The row data container.
|
||||
*/
|
||||
protected void collectRowData(RowObject rowObject, TableRowData rowData) {
|
||||
Object item = rowObject.value;
|
||||
|
||||
rowBackgroundColorCustom.refresh(item);
|
||||
rowData.setBackgroundColor(rowBackgroundColorCustom.getValue(item));
|
||||
rowForegroundColorCustom.refresh(item);
|
||||
rowData.setForegroundColor(rowForegroundColorCustom.getValue(item));
|
||||
rowFont.refresh(item);
|
||||
rowData.setFont(rowFont.getValue(item));
|
||||
}//collectRowData()//
|
||||
/**
|
||||
* Creates a new data container for the table row.
|
||||
* <p>Subclasses that add row data elements should override this.</p>
|
||||
* @return The new container for row data.
|
||||
*/
|
||||
protected TableRowData createTableRowData() {
|
||||
return new TableRowData(new TableCellData[getColumnCount()]);
|
||||
}//createTableRowData()//
|
||||
/**
|
||||
* Creates a new data container for the table cell.
|
||||
* <p>Subclasses that add row data elements should override this.</p>
|
||||
* @return The new container for cell data.
|
||||
*/
|
||||
protected TableCellData createTableCellData() {
|
||||
return new TableCellData();
|
||||
}//createTableRowData()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.tcv.view.IViewComponent#processMessage(com.foundation.tcv.model.ViewMessage)
|
||||
*/
|
||||
public Object processMessage(ViewMessage viewMessage) {
|
||||
Object retVal = null;
|
||||
|
||||
switch(viewMessage.getMessageNumber()) {
|
||||
case MESSAGE_VIEW_SYNCHRONIZE_SELECTION: { //Receive the selection information from the client.//
|
||||
Object messageData = viewMessage.getMessageData();
|
||||
|
||||
if(getAllowMultiSelection()) {
|
||||
int[] selectionObjectIds = (int[]) messageData;
|
||||
ICollection modelSelections = getModelSelections();
|
||||
|
||||
//Prevent the selection additions from causing a feedback loop.//
|
||||
suspendSelectionHooks = true;
|
||||
|
||||
try {
|
||||
//We require that the collection for the selections be created by the model.//
|
||||
if(modelSelections != null) {
|
||||
if(selectionObjectIds != null) {
|
||||
LiteHashSet selectedRowSet = new LiteHashSet(selectionObjectIds.length, LiteHashSet.DEFAULT_LOAD_FACTOR, Comparator.getIdentityComparator(), LiteHashSet.STYLE_ADD_DUPLICATES);
|
||||
IIterator iterator = modelSelections.iterator();
|
||||
LiteList removed = new LiteList(modelSelections.getSize());
|
||||
|
||||
for(int index = 0; index < selectionObjectIds.length; index++) {
|
||||
selectedRowSet.add(getRowObject(selectionObjectIds[index]).value);
|
||||
}//for//
|
||||
|
||||
//Iterate over the model's selections, removing those that are not currently selected and tracking those not yet in the model selection collection.//
|
||||
while(iterator.hasNext()) {
|
||||
Object nextValue = iterator.next();
|
||||
RowObject nextRowObject = nextValue == null ? null : getRowObject(nextValue);
|
||||
|
||||
if(nextRowObject != null) {
|
||||
//Check to see if the model selection is in the view.//
|
||||
if(!selectedRowSet.remove(nextRowObject.value)) {
|
||||
//Remove the selection from the model if it is not currently selected in the view.//
|
||||
removed.add(nextValue);
|
||||
}//if//
|
||||
}//if//
|
||||
else {
|
||||
//Remove the model selection since it is invalid.//
|
||||
removed.add(nextValue);
|
||||
}//else//
|
||||
}//while//
|
||||
|
||||
//Add any selections not already in the model selection collection.//
|
||||
modelSelections.replaceAll(removed, selectedRowSet);
|
||||
}//if//
|
||||
else {
|
||||
modelSelections.removeAll();
|
||||
}//else//
|
||||
}//if//
|
||||
}//try//
|
||||
finally {
|
||||
suspendSelectionHooks = false;
|
||||
}//finally//
|
||||
}//if//
|
||||
else {
|
||||
int selectedObjectId = messageData != null ? ((Integer) messageData).intValue() : -1;
|
||||
RowObject selectedRowObject = (RowObject) (selectedObjectId >= 0 ? getRowObject(selectedObjectId) : null);
|
||||
|
||||
setModelSelection(selectedRowObject == null ? null : selectedRowObject.value);
|
||||
}//else//
|
||||
|
||||
if(getAutoValidate()) {
|
||||
postSynchronizeValidate();
|
||||
}//if//
|
||||
break;
|
||||
}//case//
|
||||
default: {
|
||||
retVal = super.processMessage(viewMessage);
|
||||
}//default//
|
||||
}//switch//
|
||||
|
||||
return retVal;
|
||||
}//processMessage()//
|
||||
/**
|
||||
* Sets the component's default background color.
|
||||
* @param backgroundColor The default background color.
|
||||
*/
|
||||
public void setRowBackgroundColor(JefColor backgroundColor) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColor.setDefaultValue(backgroundColor);
|
||||
}//setRowHeaderBackgroundColor()//
|
||||
/**
|
||||
* Sets the component's default background color.
|
||||
* @param backgroundColor The default background color.
|
||||
*/
|
||||
public void setRowBackgroundColor(ResourceReference backgroundColor) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColor.setDefaultValue(backgroundColor);
|
||||
}//setRowHeaderBackgroundColor()//
|
||||
/**
|
||||
* Sets the component's default foreground color.
|
||||
* @param foregroundColor The default foreground color.
|
||||
*/
|
||||
public void setRowForegroundColor(JefColor foregroundColor) {
|
||||
verifyThread();
|
||||
this.rowForegroundColor.setDefaultValue(foregroundColor);
|
||||
}//setRowHeaderForegroundColor()//
|
||||
/**
|
||||
* Sets the component's default foreground color.
|
||||
* @param foregroundColor The default foreground color.
|
||||
*/
|
||||
public void setRowForegroundColor(ResourceReference foregroundColor) {
|
||||
verifyThread();
|
||||
this.rowForegroundColor.setDefaultValue(foregroundColor);
|
||||
}//setRowHeaderForegroundColor()//
|
||||
/**
|
||||
* Sets the component's default background alternate color.
|
||||
* @param backgroundColorAlt The default background alternate color.
|
||||
*/
|
||||
public void setRowBackgroundColorAlt(JefColor backgroundColorAlt) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColorAlt.setDefaultValue(backgroundColorAlt);
|
||||
}//setRowHeaderBackgroundColorAlt()//
|
||||
/**
|
||||
* Sets the component's default background alternate color.
|
||||
* @param backgroundColorAlt The default background alternate color.
|
||||
*/
|
||||
public void setRowBackgroundColorAlt(ResourceReference backgroundColorAlt) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColorAlt.setDefaultValue(backgroundColorAlt);
|
||||
}//setRowHeaderBackgroundColorAlt()//
|
||||
/**
|
||||
* Sets the component's default foreground alternate color.
|
||||
* @param foregroundColorAlt The default foreground alternate color.
|
||||
*/
|
||||
public void setRowForegroundColorAlt(JefColor foregroundColorAlt) {
|
||||
verifyThread();
|
||||
this.rowForegroundColorAlt.setDefaultValue(foregroundColorAlt);
|
||||
}//setRowHeaderForegroundColorAlt()//
|
||||
/**
|
||||
* Sets the component's default foreground alternate color.
|
||||
* @param foregroundColorAlt The default foreground alternate color.
|
||||
*/
|
||||
public void setRowForegroundColorAlt(ResourceReference foregroundColorAlt) {
|
||||
verifyThread();
|
||||
this.rowForegroundColorAlt.setDefaultValue(foregroundColorAlt);
|
||||
}//setRowHeaderForegroundColorAlt()//
|
||||
/**
|
||||
* Sets the component's default selection gradient.
|
||||
* @param selectionGradient The default selection gradient.
|
||||
*/
|
||||
public void setRowSelectionGradient(JefGradient selectionGradient) {
|
||||
verifyThread();
|
||||
this.rowSelectionGradient.setDefaultValue(selectionGradient);
|
||||
}//setRowHeaderSelectionGradient()//
|
||||
/**
|
||||
* Sets the component's default selection gradient.
|
||||
* @param selectionGradient The default selection gradient.
|
||||
*/
|
||||
public void setRowSelectionGradient(ResourceReference selectionGradient) {
|
||||
verifyThread();
|
||||
this.rowSelectionGradient.setDefaultValue(selectionGradient);
|
||||
}//setRowSelectionGradient()//
|
||||
/**
|
||||
* Sets the font for the row header. This will be the default font if there is a font attribute associated with this component.
|
||||
* @param font The default font metadata.
|
||||
*/
|
||||
public void setRowFont(JefFont[] font) {
|
||||
verifyThread();
|
||||
this.rowFont.setDefaultValue(font);
|
||||
}//setRowHeaderFont()//
|
||||
/**
|
||||
* Sets the font for the row header. This will be the default font if there is a font attribute associated with this component.
|
||||
* @param font The default font metadata.
|
||||
*/
|
||||
public void setRowFont(ResourceReference font) {
|
||||
verifyThread();
|
||||
this.rowFont.setDefaultValue(font);
|
||||
}//setRowHeaderFont()//
|
||||
/**
|
||||
* Sets the height for the rows.
|
||||
* @param height The row height in pixels.
|
||||
*/
|
||||
public void setRowHeight(Integer height) {
|
||||
verifyThread();
|
||||
this.rowHeight.setDefaultValue(height);
|
||||
}//setRowHeight()//
|
||||
/**
|
||||
* Sets the association container used to access the row background color for each row.
|
||||
* <p>The resulting value will override the row's normal color.</p>
|
||||
* @param container The row background color association metadata.
|
||||
*/
|
||||
public void setRowBackgroundColorCustomAssociation(MultiAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColorCustom.setAssociations(container);
|
||||
}//setRowBackgroundColorCustomAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row foreground color for each row.
|
||||
* <p>The resulting value will override the row's normal color.</p>
|
||||
* @param container The row foreground color association metadata.
|
||||
*/
|
||||
public void setRowForegroundColorCustomAssociation(MultiAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowForegroundColorCustom.setAssociations(container);
|
||||
}//setRowForegroundColorCustomAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row background color.
|
||||
* @param container The row background color association metadata.
|
||||
*/
|
||||
public void setRowBackgroundColorAssociation(SingleAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColor.setAssociations(container);
|
||||
}//setRowBackgroundColorAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row foreground color.
|
||||
* @param container The row foreground color association metadata.
|
||||
*/
|
||||
public void setRowForegroundColorAssociation(SingleAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowForegroundColor.setAssociations(container);
|
||||
}//setRowForegroundColorAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the alternate row background color.
|
||||
* @param container The alternate row background color association metadata.
|
||||
*/
|
||||
public void setRowBackgroundColorAltAssociation(SingleAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowBackgroundColorAlt.setAssociations(container);
|
||||
}//setRowBackgroundColorAltAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the alternate row foreground color.
|
||||
* @param container The alternate row foreground color association metadata.
|
||||
*/
|
||||
public void setRowForegroundColorAltAssociation(SingleAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowForegroundColorAlt.setAssociations(container);
|
||||
}//setRowForegroundColorAltAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row selection color.
|
||||
* @param container The row selection color association metadata.
|
||||
*/
|
||||
public void setRowSelectionGradientAssociation(AssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowSelectionGradient.setAssociations(container);
|
||||
}//setRowSelectionGradientAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row font.
|
||||
* @param container The row font association metadata.
|
||||
*/
|
||||
public void setRowFontAssociation(MultiAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowFont.setAssociations(container);
|
||||
}//setRowFontAssociation()//
|
||||
/**
|
||||
* Sets the association container used to access the row height.
|
||||
* @param container The row font association metadata.
|
||||
*/
|
||||
public void setRowHeightAssociation(SingleAssociationContainer container) {
|
||||
verifyThread();
|
||||
this.rowHeight.setAssociations(container);
|
||||
}//setRowHeightAssociation()//
|
||||
/**
|
||||
* Determines whether the control is capable of processing collection item decorations.
|
||||
* @return Whether the control can handle collection item decorations.
|
||||
*/
|
||||
protected boolean canDecorate() {
|
||||
return true;
|
||||
}//canDecorate()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.controller.IDecorationMultiListener#isListening(java.lang.Class, java.lang.Object, com.foundation.metadata.Attribute)
|
||||
*/
|
||||
public boolean isListening(Class decorationType, Object object, Attribute attribute) {
|
||||
return super.isListening(decorationType, object, attribute) && (HighlightDecoration.class.isAssignableFrom(decorationType) || ImageDecoration.class.isAssignableFrom(decorationType));
|
||||
}//isListening()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.controller.IDecorationMultiListener#addDecoration(com.foundation.view.AbstractDecoration, java.lang.Object, com.foundation.metadata.Attribute)
|
||||
*/
|
||||
public void addDecoration(AbstractDecoration decoration, Object object, Attribute attribute) {
|
||||
if(decoration instanceof HighlightDecoration) {
|
||||
sendMessage(MESSAGE_ADD_ROW_HIGHLIGHT_DECORATION, decoration, null, getRowObject(object).objectId, -1);
|
||||
}//if//
|
||||
else if(decoration instanceof ImageDecoration) { //TODO: Support ControlDecoration also or instead?
|
||||
DecorationData decorationData = (DecorationData) decorationDataMap.get(decoration);
|
||||
|
||||
if(decorationData == null) {
|
||||
decorationData = new DecorationData((ImageDecoration) decoration);
|
||||
decorationDataMap.put(decoration, decorationData);
|
||||
sendMessage(MESSAGE_ADD_ROW_IMAGE_DECORATION, decoration, null, getRowObject(object).objectId, decorationData.decorationId);
|
||||
}//if//
|
||||
else {
|
||||
decorationData.incrementReferenceCount();
|
||||
sendMessage(MESSAGE_ADD_ROW_IMAGE_DECORATION, null, null, getRowObject(object).objectId, decorationData.decorationId);
|
||||
}//else//
|
||||
}//else if//
|
||||
}//addDecoration()//
|
||||
/* (non-Javadoc)
|
||||
* @see com.foundation.controller.IDecorationMultiListener#removeDecoration(com.foundation.view.AbstractDecoration, java.lang.Object, com.foundation.metadata.Attribute)
|
||||
*/
|
||||
public void removeDecoration(AbstractDecoration decoration, Object object, Attribute attribute) {
|
||||
if(decoration instanceof HighlightDecoration) {
|
||||
sendMessage(MESSAGE_REMOVE_ROW_HIGHLIGHT_DECORATION, null, null, getRowObject(object).objectId, -1);
|
||||
}//if//
|
||||
else if(decoration instanceof ImageDecoration) {
|
||||
DecorationData decorationData = (DecorationData) decorationDataMap.get(decoration);
|
||||
|
||||
if(decorationData.decrementReferenceCount() == 0) {
|
||||
decorationDataMap.remove(decoration);
|
||||
}//if//
|
||||
|
||||
sendMessage(MESSAGE_REMOVE_ROW_IMAGE_DECORATION, null, null, getRowObject(object).objectId, decorationData.decorationId);
|
||||
}//else if//
|
||||
}//removeDecoration()//
|
||||
}//TableComponent//
|
||||
Reference in New Issue
Block a user