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;
24  
25  import java.awt.BorderLayout;
26  import java.awt.Color;
27  import java.awt.datatransfer.DataFlavor;
28  import java.awt.event.ActionEvent;
29  import java.awt.event.MouseAdapter;
30  import java.awt.event.MouseEvent;
31  import java.awt.event.MouseMotionListener;
32  import java.beans.PropertyVetoException;
33  import java.util.ArrayList;
34  import java.util.HashMap;
35  import java.util.Iterator;
36  import java.util.Map;
37  
38  import javax.swing.AbstractAction;
39  import javax.swing.Action;
40  import javax.swing.JComponent;
41  import javax.swing.JPanel;
42  import javax.swing.JScrollPane;
43  import javax.swing.ListSelectionModel;
44  import javax.swing.TransferHandler;
45  
46  import com.cosylab.gui.adapters.Converter;
47  import com.cosylab.gui.components.ObjectTable;
48  import com.cosylab.gui.components.customizer.AbstractCustomizerPanel;
49  import com.cosylab.gui.components.table.cells.TableCell;
50  import com.cosylab.gui.components.util.CosyTransferHandler;
51  import com.cosylab.gui.components.util.PopupManager;
52  import com.cosylab.gui.components.util.RunnerHelper;
53  import com.cosylab.gui.components.util.ScreenCapturer;
54  import com.cosylab.gui.displayers.DataConsumer;
55  import com.cosylab.gui.displayers.DataSource;
56  import com.cosylab.gui.displayers.DataState;
57  import com.cosylab.gui.displayers.DoubleSeqConsumer;
58  import com.cosylab.gui.util.DisplayerParametersFlavor;
59  import com.cosylab.gui.util.MultipleDisplayerParametersFlavor;
60  import com.cosylab.util.CommonException;
61  
62  import de.desy.acop.displayers.selector.SelectorUtilities;
63  import de.desy.acop.displayers.table.AcopBitTableColumn;
64  import de.desy.acop.displayers.table.AcopNumericTableColumn;
65  import de.desy.acop.displayers.table.AcopStringTableColumn;
66  import de.desy.acop.displayers.table.AcopTableColumn;
67  import de.desy.acop.displayers.table.AcopTableModel;
68  import de.desy.acop.displayers.table.AcopTableParameters;
69  import de.desy.acop.displayers.table.AcopTableParametersFlavor;
70  import de.desy.acop.displayers.table.TableColumnType;
71  import de.desy.acop.displayers.tools.AcopMultipleDisplayerInfoDialog;
72  import de.desy.acop.displayers.tools.AcopTableTransferHandler;
73  import de.desy.acop.displayers.tools.ConnectionParametersFlavor;
74  import de.desy.acop.displayers.tools.MultipleAcopDisplayer;
75  import de.desy.acop.transport.AccessMode;
76  import de.desy.acop.transport.ConnectionFailed;
77  import de.desy.acop.transport.ConnectionParameters;
78  import de.desy.acop.transport.adapters.AcopTransportDataSource;
79  import de.desy.acop.transport.adapters.AdapterFactory;
80  import de.desy.acop.transport.adapters.AdapterFactoryService;
81  
82  /**
83   * <code>AcopTable</code> is a <code>MultipleAcopDisplayer</code> which is 
84   * inteded to show values of multi-channel arrays or spectrum arrays. 
85   * The values in the table are shown in columns, where each column
86   * represent one multi channel. To connect the table to some remote property
87   * one has to add the appropriate {@link AcopTableParameters} using the method
88   * {@link #addDisplayerParameters(AcopTableParameters)} or 
89   * {@link #setDisplayerParameters(AcopTableParameters[])}. Upon setting
90   * the parameters the AcopTable will determine the type of values that needs
91   * to be shown and created the appropriate {@link AcopTableColumn}. After
92   * a monitor on one of the multi-channels is no longer needed, that particular
93   * parameters should be removed from the table using the 
94   * {@link #removeDisplayerParameters(AcopTableParameters)} method.
95   * 
96   *  
97   * @author <a href="mailto:jaka.bobnar@cosylab.com">Jaka Bobnar</a>
98   * @version $Id: Templates.xml,v 1.10 2004/01/13 16:17:13 jbobnar Exp $
99   *
100  */
101 public class AcopTable extends JPanel implements MultipleAcopDisplayer<AcopTableParameters> {
102    
103 	private static final long serialVersionUID = -2993155391577813158L;
104 	private JScrollPane scrollPane;
105 	private ObjectTable table;
106 	private AcopTableModel model;
107 	private int suspended = 0;    
108 	private Map<String,AcopTableColumn> consumers= new HashMap<String,AcopTableColumn>();
109 	private HashMap<AcopTableParameters, AcopTableColumn> connections = new HashMap<AcopTableParameters, AcopTableColumn>();
110 	private DataState dataState = new DataState(DataState.NORMAL);
111 	private PopupManager popupManager;
112 	private AbstractCustomizerPanel customizer;
113 	private AcopTableParameters selectedParameters;
114 	private boolean popupEnabled;
115 	
116 	private AcopMultipleDisplayerInfoDialog dialog;
117 	
118 	/**
119 	 * Constructs new AcopTable.
120 	 *
121 	 */
122 	public AcopTable() {
123 		super();
124 		initialize();
125 		DataFlavor[] flavor = new DataFlavor[]{AcopTableParametersFlavor.FLAVOR,
126 				MultipleDisplayerParametersFlavor.FLAVOR,
127 				DisplayerParametersFlavor.FLAVOR,ConnectionParametersFlavor.FLAVOR, 
128 				DataFlavor.stringFlavor};
129 		new AcopTableTransferHandler(this, true, true, flavor, false);
130 	}
131 	
132 	/**
133 	 * Returns the parameters that are selected in the table.
134 	 * 
135 	 * @return the selected parameters
136 	 */
137 	public AcopTableParameters getSelectedParameters() {
138 		return selectedParameters;
139 	}
140 	
141 	private void initialize() {
142 		this.setLayout(new BorderLayout());
143 		scrollPane = new JScrollPane(getTable());
144 		this.add(scrollPane, BorderLayout.CENTER);
145 		setPopupEnabled(true);
146 		scrollPane.addMouseListener(getPopupManager().getMouseHook());
147 		getTable().addMouseListener(getPopupManager().getMouseHook());
148 		setNumberOfRows(20);
149 		getTable().getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
150 		getTable().addMouseListener(new MouseAdapter() {
151 			@Override
152 			public void mousePressed(MouseEvent e) {
153 				int row =getTable().getSelectedRow();
154 				int column = getTable().getSelectedColumn();
155 				if (row >= 0 && column >= 0) {
156 					Object o = getTable().getModel().getValueAt(row, column);
157 					if (o instanceof TableCell) {
158 						Object source = ((TableCell)o).getDataSource();
159 						if (source instanceof AcopTableColumn) {
160 							AcopTableParameters parameters = ((AcopTableColumn)source).getDisplayerParameters();
161 							if (SelectorUtilities.isChannel(parameters.getConnectionParameters())) {
162 								try {
163 									String device = ((String[])AdapterFactoryService.getInstance().getAdapterFactory().getCharacteristics(parameters.getConnectionParameters()).get("xLabels"))[row];
164 									ConnectionParameters cp = parameters.getConnectionParameters();
165 									ConnectionParameters newCP = new ConnectionParameters(cp.getAccessProtocol(), cp.getDeviceContext(), cp.getDeviceGroup(), device, cp.getDeviceProperty(), cp.getAccessMode(), cp.getAccessRate(), -1);
166 									selectedParameters = parameters.deriveWith(newCP);
167 									return;
168 								} catch (ConnectionFailed e1) {
169 									e1.printStackTrace();
170 								} 
171 							} 
172 
173 							if (SelectorUtilities.getSequenceLength(parameters.getConnectionParameters()) > 1) {
174 								selectedParameters = new AcopTableParameters(parameters.getConnectionParameters().deriveWithPropertySize(-1), parameters.getColumnType(), row, parameters.getConverter(), parameters.getColumnName());
175 							} else {
176 								selectedParameters = parameters.deriveWith(parameters.getConnectionParameters().deriveWithPropertySize(-1));
177 							}
178 
179 						}
180 					}
181 				}
182 			}
183 		});
184 	}
185 	
186 	/**
187 	 * Returns the JTable used by this component. User can change the table
188 	 * as he wishes and can replace any part of the table except for the
189 	 * TableModel. Thi JTable is not replaceable by other instances.
190 	 * 
191 	 * @return the JTable used by this component 
192 	 */
193 	public ObjectTable getTable() {
194 		if (table == null) {
195 			table = new ObjectTable();
196 			table.setModel(getTableModel());
197 		}
198 		return table;
199 	}
200 	
201 	private AcopTableModel getTableModel() {
202 		if (model == null) {
203 			model = new AcopTableModel();
204 		}
205 		return model;
206 	}
207 	
208 	/* (non-Javadoc)
209 	 * @see com.cosylab.gui.displayers.CommonDisplayer#cleanup()
210 	 */
211 	public void cleanup() {
212 		for(AcopTableColumn c: consumers.values()) {
213 			c.destroy();
214 		}
215 		consumers.clear();
216 	}
217 
218 	/* (non-Javadoc)
219 	 * @see com.cosylab.gui.displayers.CommonDisplayer#suspend()
220 	 */
221 	public void suspend() {
222 		suspended++;
223 	}
224 
225 	/* (non-Javadoc)
226 	 * @see com.cosylab.gui.displayers.CommonDisplayer#resume()
227 	 */
228 	public synchronized void resume() {
229 		if (suspended>0) {
230 			suspended--;
231 		}
232 	}
233 
234 	/* (non-Javadoc)
235 	 * @see com.cosylab.gui.displayers.CommonDisplayer#isSuspended()
236 	 */
237 	public boolean isSuspended() {
238 		return suspended>0;
239 	}
240 
241 	/* (non-Javadoc)
242 	 * @see com.cosylab.gui.displayers.DataStateProvider#getDataState()
243 	 */
244 	public DataState getDataState() {
245 		return dataState;
246 	}
247 
248 	/* (non-Javadoc)
249 	 * @see com.cosylab.gui.displayers.MultipleDataConsumer#getConsumer(java.lang.String, java.lang.Class)
250 	 */
251 	public <D extends DataConsumer> D getConsumer(String name, Class<D> type) {
252 		return getConsumer(name, name, type);
253 	}
254 	
255 	private <D extends DataConsumer> D getConsumer(String uniqueName, String shortName, Class<D> type) {
256 				
257 		if (consumers.containsKey(uniqueName)) {
258 			return type.cast(consumers.get(uniqueName));
259 		}
260 		
261 		AcopTableColumn c = null;
262 		if (type.isAssignableFrom(AcopNumericTableColumn.class)) {
263 			c = new AcopNumericTableColumn(this, uniqueName, shortName);
264 		} else if (type.isAssignableFrom(AcopBitTableColumn.class)) {
265 			c = new AcopBitTableColumn(this, uniqueName, shortName);
266 		} else if (type.isAssignableFrom(AcopStringTableColumn.class)) {
267 			c = new AcopStringTableColumn(this, uniqueName, shortName);
268 		}
269 		
270 		if (c != null) {
271 			getTableModel().addColumn(c);
272 			consumers.put(uniqueName,c);
273 			return type.cast(c);
274 		}
275 		
276 		return null;
277 	}
278 
279 	/* (non-Javadoc)
280 	 * @see com.cosylab.gui.displayers.MultipleDataConsumer#releaseConsumer(com.cosylab.gui.displayers.DataConsumer)
281 	 */
282 	public void releaseConsumer(DataConsumer consumer) {
283 		consumers.remove(consumer.getName()).destroy();
284 		getTableModel().removeColumn((AcopTableColumn)consumer);
285 	}
286 
287 	/* (non-Javadoc)
288 	 * @see com.cosylab.gui.displayers.MultipleDataConsumer#getConsumers()
289 	 */
290 	public DataConsumer[] getConsumers() {
291 		return consumers.values().toArray(new DataConsumer[consumers.size()]);
292 	}
293 
294 	/* (non-Javadoc)
295 	 * @see com.cosylab.gui.displayers.MultipleDataConsumer#getSupportedConsumerTypes()
296 	 */
297 	@SuppressWarnings("unchecked")
298 	public Class<DataConsumer>[] getSupportedConsumerTypes() {
299 		return new Class[]{DoubleSeqConsumer.class};
300 	}
301 	
302 	private static String[] getDeviceNames(AcopTableParameters parameters) throws ConnectionFailed {
303 		AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
304 		String[] names = (String[])factory.getCharacteristics(parameters.getConnectionParameters()).get("xLabels");
305 		int size = parameters.getConnectionParameters().getPropertySize();
306 		if (size <= 0 || size == names.length) {
307 			return names;
308 		}
309 		String[] retVal = new String[size];
310 		for (int i = 0; i < size; i++) {
311 			retVal[i] = names[i];
312 		}
313 		return retVal;
314 	}
315 	
316 	/*
317 	 * (non-Javadoc)
318 	 * @see de.desy.acop.displayers.AcopMultipleDisplayerConnector#addConnectionParameters(de.desy.acop.transport.ConnectionParameters)
319 	 */
320 	public void addDisplayerParameters(AcopTableParameters parameters) throws CommonException, PropertyVetoException {
321 		if (parameters == null) return;
322 		if (connections.get(parameters) != null) {
323 			return;         
324 		}  
325 		suspend();
326 		AcopTableParameters[] old = getDisplayerParameters();
327 		AcopTableColumn consumer = null;
328 		AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
329 		if (parameters.getColumnType() == TableColumnType.NAME) {
330 			consumer = getConsumer(parameters.toString(), parameters.getName(), AcopStringTableColumn.class);
331 			consumer.setDisplayerParameters(parameters);
332 			((AcopStringTableColumn)consumer).updateValue(0,getDeviceNames(parameters));
333 		} else {
334 			if (parameters.getColumnType() == TableColumnType.STRING) {
335 				consumer = getConsumer(parameters.toString(), parameters.getName(), AcopStringTableColumn.class);
336 			} else if (parameters.getColumnType() == TableColumnType.BIT) {
337 				consumer = getConsumer(parameters.toString(), parameters.getName(), AcopBitTableColumn.class);
338 			} else {
339 				consumer = getConsumer(parameters.toString(), parameters.getName(), AcopNumericTableColumn.class);
340 			}
341 			AcopTransportDataSource ds = factory.createDataSource(parameters.getConnectionParameters());
342 			if (parameters.getConverter() != null && !parameters.getColumnType().equals(TableColumnType.STRING)){
343 				Converter c = parameters.getConverter();
344 				c.addConsumer(consumer);
345 				ds.addConsumer(c);
346 			}
347 			else {
348 				ds.addConsumer(consumer);
349 			}
350 			consumer.setDisplayerParameters(parameters);
351 		}
352 
353 		connections.put(parameters, consumer);
354 		resume();
355 		firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
356     }
357  	
358 	/**
359 	 * 
360 	 * @see de.desy.acop.displayers.tools.MultipleAcopDisplayer#addConnectionParameters(de.desy.acop.transport.ConnectionParameters)
361 	 * @deprecated use {@link #addDisplayerParameters(AcopTableParameters)}
362 	 */
363 	public void addConnectionParameters(ConnectionParameters parameters) throws CommonException, PropertyVetoException {
364 		
365 		addDisplayerParameters(new AcopTableParameters(parameters, TableColumnType.VALUE, null));
366     }
367 	
368 	/*
369 	 * (non-Javadoc)
370 	 * @see de.desy.acop.displayers.AcopMultipleDisplayerConnector#getConnectionParameters()
371 	 */
372 	public AcopTableParameters[] getDisplayerParameters() {
373 		AcopTableParameters[] params = new AcopTableParameters[connections.keySet().size()];
374 	    return connections.keySet().toArray(params);
375     }
376 	
377 	/**
378 	 * (non-Javadoc)
379 	 * @see de.desy.acop.displayers.tools.MultipleAcopDisplayer#getConnectionParameters()
380 	 * @deprecated use {@link #getDisplayerParameters()}
381 	 */
382 	public ConnectionParameters[] getConnectionParameters() {
383 		
384 		AcopTableParameters[] agp = getDisplayerParameters();
385 		ConnectionParameters[] cp = new ConnectionParameters[agp.length];
386 		for (int i = 0; i < agp.length; i++) {
387 			cp[i] = agp[i].getConnectionParameters();
388 		}
389 		return cp;
390 	}
391 	
392 	/*
393 	 * (non-Javadoc)
394 	 * @see de.desy.acop.displayers.AcopMultipleDisplayerConnector#removeConnectionParameters(de.desy.acop.transport.ConnectionParameters)
395 	 */
396 	public DataSource removeDisplayerParameters(AcopTableParameters parameters) {
397 		AcopTableParameters[] old = getDisplayerParameters();
398 		AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
399 		AcopTableColumn consumer = connections.remove(parameters);
400 		if (consumer == null) return null;
401 		DataSource ds = null;
402 		if (parameters.getColumnType() != TableColumnType.NAME) {
403 			ds = factory.releaseDataSource(parameters.getConnectionParameters());
404 			if (parameters.getConverter() != null) {
405 				ds.removeConsumer(parameters.getConverter());
406 				parameters.getConverter().removeConsumer(consumer);
407 			} else {
408 				ds.removeConsumer(consumer);
409 			}
410 		}
411 		releaseConsumer(consumer);
412 		firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
413 	    return ds;
414 	    
415     }
416 	
417 	/**
418 	 * 
419 	 * @see de.desy.acop.displayers.tools.MultipleAcopDisplayer#removeConnectionParameters(de.desy.acop.transport.ConnectionParameters)
420 	 * @deprecated use {@link #removeDisplayerParameters(AcopTableParameters)}
421 	 */
422 	public DataSource removeConnectionParameters(ConnectionParameters parameters) {
423 		AcopTableParameters[] old = getDisplayerParameters();
424 		DataSource ds = null;
425 		for (AcopTableParameters p : old) {
426 			if (p.getConnectionParameters().equals(parameters)) {
427 				AdapterFactory factory = AdapterFactoryService.getInstance().getAdapterFactory();
428 				AcopTableColumn consumer = connections.remove(parameters);
429 				if (consumer == null) continue;
430 				ds = factory.releaseDataSource(parameters);
431 				ds.removeConsumer(consumer);
432 				releaseConsumer(consumer);
433 			}
434 		}
435 		firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, getDisplayerParameters());
436 		return ds;
437 	}
438 	
439 	/*
440 	 * (non-Javadoc)
441 	 * @see de.desy.acop.displayers.AcopMultipleDisplayerConnector#setConnectionParameters(de.desy.acop.transport.ConnectionParameters[])
442 	 */
443 	public void setDisplayerParameters(AcopTableParameters[] parameters) throws CommonException, PropertyVetoException {
444 		AcopTableParameters[] old = getDisplayerParameters();
445 		ArrayList<AcopTableParameters> toBeRemoved = new ArrayList<AcopTableParameters>();
446 		Iterator<AcopTableParameters> it = connections.keySet().iterator();
447 		while(it.hasNext()) {
448 			toBeRemoved.add(it.next());
449 		}
450 		
451 		ArrayList<AcopTableParameters> toBeAdded = new ArrayList<AcopTableParameters>();
452 	
453 		for (AcopTableParameters p : parameters) {
454 			if (toBeRemoved.contains(p)) {
455 				toBeRemoved.remove(p);
456 			} else {
457 				toBeAdded.add(p);
458 			}
459 		}
460 		
461 		for(AcopTableParameters p : toBeRemoved) {
462 			removeDisplayerParameters(p);
463 		}
464 		
465 		for(AcopTableParameters p : toBeAdded) {
466 			addDisplayerParameters(p);
467 		}
468 		
469 		firePropertyChange(MultipleAcopDisplayer.DISPLAYER_PARAMETERS_PROPERTY, old, parameters);
470     }
471 	
472 	/*
473 	 * (non-Javadoc)
474 	 * @see de.desy.acop.displayers.tools.MultipleAcopDisplayer#setConnectionParameters(de.desy.acop.transport.ConnectionParameters[])
475 	 */
476 	public void setConnectionParameters(ConnectionParameters[] parameters) throws CommonException, PropertyVetoException {
477 		  
478 		AcopTableParameters[] agp = new AcopTableParameters[parameters.length];
479 		for (int i = 0; i < parameters.length; i++) {
480 			agp[i] = new AcopTableParameters(parameters[i], TableColumnType.VALUE, null);
481 		}
482 		setDisplayerParameters(agp);
483 	}
484 	
485 	/**
486 	 * Returns the Customizer intance for this displayer.
487 	 *
488 	 * @return the Customizer intance for this displayer
489 	 */
490 	public AbstractCustomizerPanel getCustomizer()
491 	{
492 		if (customizer == null) {
493 			customizer = AbstractCustomizerPanel.findCustomizer(this);
494 		}
495 		return customizer;
496 	}
497 
498 	/*
499 	 * (non-Javadoc)
500 	 * @see com.cosylab.gui.components.util.PopupManageable#getPopupManager()
501 	 */
502 	public PopupManager getPopupManager() {
503 		if (popupManager == null) {
504 			popupManager = new PopupManager(this, false);
505 			popupManager.addAction(new AbstractAction("Preferences...") {
506 				private static final long serialVersionUID = 1L;
507 				public void actionPerformed(ActionEvent e)
508 				{
509 					getCustomizer().showDialog();
510 				}
511 			});
512 			
513 			popupManager.addAction(new AbstractAction("Capture screen..."){
514 				private static final long serialVersionUID = 1L;
515 
516 				public void actionPerformed(ActionEvent e){
517 				   	ScreenCapturer sc = new ScreenCapturer(AcopTable.this);
518 					sc.showScreenDialog();
519 				   }
520 			});
521 			
522 			popupManager.addAction(new AbstractAction("Info...") {
523 				private static final long serialVersionUID = 1L;
524 				public void actionPerformed(ActionEvent e)
525 				{
526 					getInfoDialog().setVisible(true);
527 				}
528 			});
529 		}
530 		return popupManager;
531 	}
532 	
533 	/**
534 	 * Return true if the popup menu is enabled or false otherwise.
535 	 * 
536 	 * @return true if popup is enabled
537 	 */
538 	public boolean isPopupEnabled() {
539 		return popupEnabled;
540 	}
541 	
542 	/**
543 	 * Enables or disables the popup menu.
544 	 * 
545 	 * @param enabled true if enable or false if disableds
546 	 */
547 	public void setPopupEnabled(boolean enabled) {
548 		if (popupEnabled == enabled) return;
549 		popupEnabled = enabled;
550 		if (enabled) {
551 			addMouseListener(getPopupManager().getMouseHook());
552 		} else {
553 			removeMouseListener(getPopupManager().getMouseHook());
554 		}
555 		firePropertyChange("popupEnabled",!popupEnabled,popupEnabled);
556 	}
557 	
558 	/**
559 	 * Returns the number of rows displayed in the table.
560 	 * @return
561 	 */
562 	public int getNumberOfRows() {
563 		return getTableModel().getRowCount();
564 	}
565 	
566 	/**
567 	 * Sets the number of rows displayer in the table.
568 	 * @param numberOfRows
569 	 */
570 	public void setNumberOfRows(int numberOfRows) {
571 		getTableModel().setRowCount(numberOfRows);
572 	}
573 	
574 	/*
575 	 * (non-Javadoc)
576 	 * @see javax.swing.JComponent#setTransferHandler(javax.swing.TransferHandler)
577 	 */
578 	@Override
579 	public void setTransferHandler(TransferHandler newHandler) {
580 		super.setTransferHandler(newHandler);
581 		CosyTransferHandler.registerTransferHandler(this, newHandler, new JComponent[]{scrollPane, getTable()});
582 	}
583 
584 	
585 	/*
586 	 * (non-Javadoc)
587 	 * @see java.awt.Component#removeMouseMotionListener(java.awt.event.MouseMotionListener)
588 	 */
589 	@Override
590 	public synchronized void removeMouseMotionListener(MouseMotionListener l) {
591 		super.removeMouseMotionListener(l);
592 		scrollPane.removeMouseMotionListener(l);
593 		getTable().removeMouseMotionListener(l);
594 	}
595 	
596 	/**
597 	 * Enables/disables mouse dragging. Dragging can only be enabled if
598 	 * this component uses CosyTransferHandler.
599 	 * 
600 	 * @param enabled
601 	 */
602 	public void setDragEnabled(boolean enabled) {
603 		if (getTransferHandler() instanceof CosyTransferHandler) {
604 			if (((CosyTransferHandler)getTransferHandler()).isExportEnabled() == enabled) return;
605 			
606 			((CosyTransferHandler)getTransferHandler()).setExportEnabled(enabled, this);
607 		}
608 	}
609 	
610 	/**
611 	 * Returns true if drag is enabled.
612 	 * 
613 	 * @return true if drag is enabled
614 	 */
615 	public boolean isDragEnabled() {
616 		if (getTransferHandler() instanceof CosyTransferHandler) {
617 			return ((CosyTransferHandler)getTransferHandler()).isExportEnabled();
618 		} else {
619 			return getTransferHandler() != null;
620 		}
621 	}
622 	
623 	/**
624 	 * Enable/disable the mouse drop. Drop can only be enabled if this component uses
625 	 * CosyTransferHandler.
626 	 * 
627 	 * @param enabled
628 	 */
629 	public void setDropEnabled(boolean enabled) {
630 		if (getTransferHandler() instanceof CosyTransferHandler) {
631 			if (((CosyTransferHandler)getTransferHandler()).isReceiveEnabled() == enabled) return;
632 			
633 			((CosyTransferHandler)getTransferHandler()).setReceiveEnabled(enabled, this);
634 		}
635 	}
636 	
637 	/**
638 	 * Returns true if drop is enabled.
639 	 * 
640 	 * @return true if drop is enabled
641 	 */
642 	public boolean isDropEnabled() {
643 		if (getTransferHandler() instanceof CosyTransferHandler) {
644 			return ((CosyTransferHandler)getTransferHandler()).isReceiveEnabled();
645 		} else {
646 			return getTransferHandler() != null;
647 		}
648 	}
649 	
650 	/**
651 	 * Returns the info dialog associated with this table.
652 	 * 
653 	 * @return the info dialog
654 	 */
655 	public AcopMultipleDisplayerInfoDialog getInfoDialog() {
656 		if (dialog == null) {
657 			dialog = new AcopMultipleDisplayerInfoDialog(this);
658 		}
659 		return dialog;
660 	}
661 	
662 	/**
663 	 * Enables/disables Properties item in the popup menu.
664 	 * @param enable
665 	 */
666 	public void setPropertiesPopupEnabled(boolean enable) {
667 		Action[] actions = getPopupManager().getActions();
668 		for (Action a : actions) {
669 			if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
670 				a.setEnabled(enable);
671 				return;
672 			}
673 		}
674 	}
675 	
676 	/**
677 	 * Returns true if Properties item is enabled in the popup menu.
678 	 * @return
679 	 */
680 	public boolean isPropertiesPopupEnabled() {
681 		Action[] actions = getPopupManager().getActions();
682 		for (Action a : actions) {
683 			if (a != null && "Preferences...".equals(a.getValue(Action.NAME))) {
684 				return a.isEnabled();
685 			}
686 		}
687 		return false;
688 	}
689 	
690 	/**
691 	 * Enables/disables reordering of the columns in the table in runtime.
692 	 * 
693 	 * @param reorderingAllowed true if reordering should be allowed
694 	 */
695 	public void setReorderingAllowed(boolean reorderingAllowed) {
696 		if (getReorderingAllowed() == reorderingAllowed) return;
697 		getTable().getTableHeader().setReorderingAllowed(reorderingAllowed);
698 		firePropertyChange("reordeningAllowed", !reorderingAllowed, reorderingAllowed);
699 	}
700 	
701 	/**
702 	 * Returns true if reordering of columns in the table is allowed in runtime.
703 	 * 
704 	 * @return true if reordening is allowed
705 	 */
706 	public boolean getReorderingAllowed() {
707 		return getTable().getTableHeader().getReorderingAllowed();
708 	}	
709 	
710 	/*
711 	 * (non-Javadoc)
712 	 * @see javax.swing.JComponent#setBackground(java.awt.Color)
713 	 */
714 	@Override
715 	public void setBackground(Color bg) {
716 		super.setBackground(bg);
717 		getTable().setBackground(bg);
718 	}
719 	
720 	/*
721 	 * (non-Javadoc)
722 	 * @see javax.swing.JComponent#setForeground(java.awt.Color)
723 	 */
724 	@Override
725 	public void setForeground(Color fg) {
726 		super.setForeground(fg);
727 		getTable().setForeground(fg);
728 	}
729 	
730 	
731 
732 	public static void main(String[] args) throws CommonException, PropertyVetoException {
733 		AcopTable table = new AcopTable();
734 		table.setForeground(Color.RED);
735 //		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","TempModule0", "Temperature", AccessMode.POLL, 1000), TableDisplayType.NAME));
736 //		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","TempModule0", "Temperature", AccessMode.POLL, 1000), TableDisplayType.BIT));
737 //		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","TempModule0", "Temperature", AccessMode.POLL, 1000), TableDisplayType.VALUE));
738 //		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","Device 0", "Sine", AccessMode.POLL, 1000), TableDisplayType.NAME));
739 //		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","Device 0", "Sine", AccessMode.POLL, 1000), TableDisplayType.BIT));
740 		table.addDisplayerParameters(new AcopTableParameters(new ConnectionParameters("TINE", "WORKSHOP", "WKSineGen","Device 0", "Amplitude", AccessMode.POLL, 1000), TableColumnType.VALUE, "bla"));
741 		
742 		RunnerHelper.runComponent(table, 800, 600);
743 	}
744 	
745 }