/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package org.acme.example.view;
import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.components.FeedProvider;
import gov.nasa.arc.mct.components.Placeholder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.table.AbstractTableModel;
@SuppressWarnings("serial")
class MultiColTableModel extends AbstractTableModel {
private List<AbstractComponent> childrenList;
private ViewSettings settings;
private Map<String, Object> values = new HashMap<String, Object>();
private Map<String,List<Integer>> componentLocations;
public MultiColTableModel(List<AbstractComponent> childrenList, ViewSettings settings) {
this.settings = settings;
this.childrenList = childrenList;
updateLocations();
}
@Override
public int getColumnCount() { return settings.getNumberOfColumns(); }
@Override
public int getRowCount() { return childrenList.size(); }
public AbstractComponent getComponentOfRow(int rowIndex) {
return childrenList.get(rowIndex);
}
@Override
public String getColumnName(int colIndex) {
ColumnType colType = settings.getColumnAtIndex(colIndex);
return colType.name();
}
private void updateLocations() {
componentLocations = new HashMap<String,List<Integer>>();
for (int row=0; row < getRowCount(); ++row) {
AbstractComponent component = childrenList.get(row);
if (component != null) {
List<Integer> locations = componentLocations.get(getKey(component));
if (locations == null) {
locations = new ArrayList<Integer>();
componentLocations.put(getKey(component), locations);
}
locations.add(row);
}
}
}
/**
* Returns a unique key for a given component. This key is used by the
* code that responds to a feed update to pass along changes to the
* component's value.
*
* @param component the component for which to determine the key
* @return a unique key for the component
*/
public String getKey(AbstractComponent component) {
AbstractComponent delegate = component;
FeedProvider fp = component.getCapability(FeedProvider.class);
if (fp != null) {
return fp.getSubscriptionId();
}
return delegate.getComponentId();
}
@Override
public Object getValueAt(int r, int c) {
ColumnType colType = settings.getColumnAtIndex(c);
Object cellDatum = null;
AbstractComponent cellComponent = childrenList.get(r);
switch(colType) {
case ID:
cellDatum = cellComponent.getExternalKey(); // Use external key if available
cellDatum = cellDatum != null ? cellDatum : cellComponent.getId(); break;
case TITLE:
cellDatum = cellComponent.getDisplayName(); break;
case VALUE:
cellDatum = getValueForComponent(cellComponent); break;
case TIME:
cellDatum = (FeedProvider) cellComponent; break;
}
if(cellDatum==null) { return "(no data)"; }
else { return cellDatum; }
}
/**
* Sets the value of an object updated by a data feed. This change
* is propagated to all table cells displaying that object.
*
* @param id the identifier for the object updated
* @param value the new value to display
*/
public void setValue(String id, Object value) {
values.put(id, value);
List<Integer> locations = componentLocations.get(id);
if (locations != null) {
for (Integer row : locations) {
fireTableCellUpdated(row, settings.getIndexForColumn(ColumnType.VALUE));
fireTableCellUpdated(row, settings.getIndexForColumn(ColumnType.TIME));
}
}
}
private Object getValueForComponent(AbstractComponent component) {
Object value = values.get(getKey(component));
if (value == null) {
DisplayedValue displayedValue = new DisplayedValue();
if (component.getCapability(Placeholder.class) != null) {
displayedValue.setValue(component.getCapability(Placeholder.class).getPlaceholderValue());
} else {
displayedValue.setValue(component.getDisplayName());
}
return displayedValue;
} else {
return value;
}
}
}