View Javadoc

1   /*
2    * Copyright (c) 2006 Stiftung Deutsches Elektronen-Synchroton,
3    * Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY.
4    *
5    * THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN "../AS IS" BASIS.
6    * WITHOUT WARRANTY OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
7    * TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR PARTICULAR PURPOSE AND
8    * NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
9    * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
10   * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
11   * THE USE OR OTHER DEALINGS IN THE SOFTWARE. SHOULD THE SOFTWARE PROVE DEFECTIVE
12   * IN ANY RESPECT, THE USER ASSUMES THE COST OF ANY NECESSARY SERVICING, REPAIR OR
13   * CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
14   * NO USE OF ANY SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
15   * DESY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
16   * OR MODIFICATIONS.
17   * THE FULL LICENSE SPECIFYING FOR THE SOFTWARE THE REDISTRIBUTION, MODIFICATION,
18   * USAGE AND OTHER RIGHTS AND OBLIGATIONS IS INCLUDED WITH THE DISTRIBUTION OF THIS
19   * PROJECT IN THE FILE LICENSE.HTML. IF THE LICENSE IS NOT INCLUDED YOU MAY FIND A COPY
20   * AT HTTP://WWW.DESY.DE/LEGAL/LICENSE.HTM
21   */
22  
23  package de.desy.acop.displayers.table;
24  
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import com.cosylab.gui.components.table.cells.TableCell;
29  import com.cosylab.gui.displayers.DataConsumer;
30  import com.cosylab.gui.displayers.DataState;
31  import com.cosylab.util.ListenerList;
32  
33  import de.desy.acop.displayers.AcopTable;
34  
35  /**
36   * <code>AcopTableColumn</code> is a <code>DataConsumer</code> which uses
37   * TableCells for displaying values. AcopTableColumn can be used in combination
38   * with <code>AcopTable</code> and can represent a single column in the
39   * table.
40   *   
41   * @author Jaka Bobnar, Cosylab
42   * @see AcopTable
43   *
44   */
45  public abstract class AcopTableColumn implements DataConsumer {
46  	
47  	private String uniqueName;
48  	private String shortName;
49  	protected AcopTable table;
50  	protected AcopTableParameters displayerParameters;
51  	protected DataState dataState = new DataState(DataState.UNDEFINED);
52  	protected TableCell[] cells;
53  	protected int rowCount = 10;
54  	protected HashMap<String, Object> characteristics = new HashMap<String, Object>();
55  	
56  	private ListenerList columnListeners = new ListenerList(TableColumnListener.class);
57  	
58  	/**
59  	 * Constructs a new AcopTableColumn
60  	 *
61  	 */
62  	public AcopTableColumn() {
63  		this(null, null, "");
64  	}
65  	
66  	/**
67  	 * Constructs a new AcopTableColumn.
68  	 * 
69  	 * @param table parent table
70  	 * @param uniqueName unique name of the column
71  	 * @param shortName short name of the column
72  	 */
73  	public AcopTableColumn(AcopTable table, String uniqueName, String shortName) {
74  		this.table = table;
75  		this.uniqueName = uniqueName;
76  		this.shortName = shortName;
77  	}
78  	
79  	/*
80  	 * (non-Javadoc)
81  	 * @see com.cosylab.gui.displayers.DataConsumer#getName()
82  	 */
83  	public String getName() {
84  		return uniqueName;
85  	}
86  	
87  	/**
88  	 * Returns the name that is printed in the table header. This is the short name
89  	 * of the column.
90  	 * 
91  	 * @return the header name
92  	 */
93  	public String getHeaderName() {
94  		return shortName;
95  	}
96  	
97  	/**
98  	 * Returns the class of the objects that this column presents. 
99  	 * @return column class
100 	 */
101 	public Class<?> getColumnClass() {
102 		return TableCell.class;
103 	}
104 	
105 	/**
106 	 * Returns the value at specified row.
107 	 * @param rowIndex
108 	 * @return
109 	 */
110 	public abstract Object getValue(int rowIndex);
111 	
112 	/**
113 	 * Sets the number of rows. When update is received only the as many rows as 
114 	 * specified here will be updated to avoid to avoid unnecessary overload. Counting
115 	 * starts at the first (most top) row.
116 	 * 
117 	 * @param rowCount new number of rows
118 	 */
119 	public void setRowCount(int rowCount) {
120 		this.rowCount = rowCount;
121 	}
122 	
123 	/**
124 	 * Returns the number of rows.
125 	 * @return number of rows in the column
126 	 */
127 	public int getRowCount() {
128 		return rowCount;
129 	}
130 	
131 	/* (non-Javadoc)
132 	 * @see com.cosylab.gui.displayers.DataConsumer#getDataConsumer(java.lang.Class)
133 	 */
134 	@SuppressWarnings("unchecked")
135     public DataConsumer getDataConsumer(Class type) {
136 		if (type.isAssignableFrom(getClass())) {
137 			return this;
138 		}
139 		return null;
140 	}
141 
142 	/* (non-Javadoc)
143 	 * @see com.cosylab.gui.displayers.DataConsumer#getDefaultDataConsumer()
144 	 */
145 	public DataConsumer getDefaultDataConsumer() {
146 		return this;
147 	}
148 
149 	/* (non-Javadoc)
150 	 * @see com.cosylab.gui.displayers.DataConsumer#updateDataState(com.cosylab.gui.displayers.DataState)
151 	 */
152 	public void updateDataState(DataState state) {
153 		if (dataState != null && dataState.equals(state)) return;
154 		dataState = state;
155 		if (cells != null) {
156 			for (int i = 0; i < cells.length && i < rowCount; i++) {
157 				if (cells[i] == null) getValue(i);
158 				setDataStateOnCell(cells[i]);
159 			}
160 		}
161 		fireColumnChanged();
162 	}
163 	
164 	/*
165 	 * (non-Javadoc)
166 	 * @see com.cosylab.gui.displayers.DataConsumer#setCharacteristics(java.util.Map)
167 	 */
168 	public void setCharacteristics(Map characteristics) {
169 		
170 		if (cells != null) {
171 			for (TableCell cell : cells) {
172 				cell.putAllCharacteristics(characteristics);
173 			}
174 		}
175 		
176 		this.characteristics.putAll(characteristics);
177 	}
178 	
179 	/**
180 	 * Destroys this column and releases any resource associated with it.
181 	 *
182 	 */
183 	public void destroy() {
184 		table = null;
185 		displayerParameters = null;
186 	}
187 	
188 	/**
189 	 * Adds a TableColumnListener which receives notifications when certain column
190 	 * values changed.
191 	 * 
192 	 * @param l
193 	 */
194 	public void addTableColumnListener(TableColumnListener l) {
195 		synchronized (columnListeners) {
196 			columnListeners.add(l);
197 		}
198 	}
199 	
200 	/**
201 	 * Removes a TableColumnListener.
202 	 * 
203 	 * @param l
204 	 */
205 	public void removeTableColumnListener(TableColumnListener l) {
206 		synchronized (columnListeners) {
207 			columnListeners.add(l);
208 		}		
209 	}
210 	
211 	protected void fireColumnChanged() {
212 		TableColumnListener[] listeners = (TableColumnListener[]) columnListeners.toArray();
213 		TableColumnEvent event = new TableColumnEvent(this);
214 		
215 		for (TableColumnListener l : listeners) {
216 			l.columnDataChanged(event);
217 		}
218 	}
219 
220 	/**
221 	 * Returns the current data state of this column.
222 	 * 
223 	 * @return the data state
224 	 */
225 	public DataState getDataState() {
226 		return dataState;
227 	}
228 	
229 	protected void setCharacteristicsOnCell(TableCell cell) {
230 		cell.putCharacteristic(TableCell.TOOLTIP, cell.getIdentifier() + " '" + cell.getValue() + "'");
231 	}
232 	
233 	protected void setDataStateOnCell(TableCell cell) {
234 		if (cell == null) return;
235 		DataState dataState = getDataState();
236 		if (dataState.type.equals(DataState.ERROR)) {
237 			cell.putCharacteristic(TableCell.SUSPENDED, false);
238 			cell.putCharacteristic(TableCell.ALARM, false);
239 			cell.putCharacteristic(TableCell.WARNING, false);
240 			cell.putCharacteristic(TableCell.TIMEOUT, false);
241 			cell.putCharacteristic(TableCell.ERROR, true);
242 		} else if (dataState.type.equals(DataState.ALARM)) {
243 			cell.putCharacteristic(TableCell.SUSPENDED, false);
244 			cell.putCharacteristic(TableCell.ALARM, true);
245 			cell.putCharacteristic(TableCell.WARNING, false);
246 			cell.putCharacteristic(TableCell.TIMEOUT, false);
247 			cell.putCharacteristic(TableCell.ERROR, false);
248 		} else if (dataState.type.equals(DataState.WARNING)) {
249 			cell.putCharacteristic(TableCell.SUSPENDED, false);
250 			cell.putCharacteristic(TableCell.ALARM, false);
251 			cell.putCharacteristic(TableCell.WARNING, true);
252 			cell.putCharacteristic(TableCell.TIMEOUT, false);
253 			cell.putCharacteristic(TableCell.ERROR, false);
254 		} else if (dataState.type.equals(DataState.TIMEOUT)) {
255 			cell.putCharacteristic(TableCell.SUSPENDED, false);
256 			cell.putCharacteristic(TableCell.ALARM, false);
257 			cell.putCharacteristic(TableCell.WARNING, false);
258 			cell.putCharacteristic(TableCell.TIMEOUT, true);
259 			cell.putCharacteristic(TableCell.ERROR, false);
260 		} else if (dataState.type.equals(DataState.TIMELAG)) {
261 			cell.putCharacteristic(TableCell.SUSPENDED, false);
262 			cell.putCharacteristic(TableCell.ALARM, false);
263 			cell.putCharacteristic(TableCell.WARNING, false);
264 			cell.putCharacteristic(TableCell.TIMEOUT, true);
265 			cell.putCharacteristic(TableCell.ERROR, false);
266 		} else if (dataState.type.equals(DataState.UNDEFINED) || dataState.type.equals(DataState.NOT_INITIALIZED)) {
267 			cell.putCharacteristic(TableCell.SUSPENDED, true);
268 			cell.putCharacteristic(TableCell.ALARM, false);
269 			cell.putCharacteristic(TableCell.WARNING, false);
270 			cell.putCharacteristic(TableCell.TIMEOUT, false);
271 			cell.putCharacteristic(TableCell.ERROR, false);
272 		} else if (dataState.type.equals(DataState.NORMAL)) {
273 			cell.putCharacteristic(TableCell.SUSPENDED, false);
274 			cell.putCharacteristic(TableCell.ALARM, false);
275 			cell.putCharacteristic(TableCell.WARNING, false);
276 			cell.putCharacteristic(TableCell.TIMEOUT, false);
277 			cell.putCharacteristic(TableCell.ERROR, false);
278 		}
279 	}
280 
281 	/**
282 	 * Returns the displayer parameters associated with this column.
283 	 * 
284 	 * @return the parameters
285 	 */
286 	public AcopTableParameters getDisplayerParameters() {
287 		return displayerParameters;
288 	}
289 
290 	/**
291 	 * Sets the displayer parameters that specify the connection point and look of
292 	 * the column.
293 	 * 
294 	 * @param displayerParameters the parameters
295 	 */
296 	public void setDisplayerParameters(AcopTableParameters displayerParameters) {
297 		this.displayerParameters = displayerParameters;
298 	}
299 }