View Javadoc

1   /*
2    * Copyright (c) 2003-2008 by Cosylab d. d.
3    *
4    * This file is part of CosyBeans-Common.
5    *
6    * CosyBeans-Common is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU General Public License as published by
8    * the Free Software Foundation, either version 3 of the License, or
9    * (at your option) any later version.
10   *
11   * CosyBeans-Common is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU General Public License for more details.
15   *
16   * You should have received a copy of the GNU General Public License
17   * along with CosyBeans-Common.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  
20  package com.cosylab.gui.components.table.renderers;
21  
22  import java.awt.Color;
23  import java.awt.Component;
24  import java.awt.Font;
25  import java.awt.Point;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.ActionListener;
28  import java.awt.event.MouseAdapter;
29  import java.awt.event.MouseEvent;
30  import java.lang.ref.WeakReference;
31  import java.util.EventObject;
32  import java.util.logging.Level;
33  import java.util.logging.Logger;
34  
35  import javax.swing.JMenuItem;
36  import javax.swing.JPopupMenu;
37  import javax.swing.JSeparator;
38  import javax.swing.JTable;
39  import javax.swing.SwingConstants;
40  import javax.swing.event.CellEditorListener;
41  import javax.swing.event.ChangeEvent;
42  import javax.swing.table.TableCellEditor;
43  
44  import com.cosylab.gui.components.ObjectTable;
45  import com.cosylab.gui.components.table.cells.Command;
46  import com.cosylab.gui.components.table.cells.DeviceCell;
47  import com.cosylab.logging.DebugLogger;
48  import com.cosylab.util.ObjectList;
49  
50  
51  /**
52   * Renderer for <code>com.cosylab.gui.components.table.cells.DeviceCell</code>
53   * cells. This implementation displays device name.
54   *
55   * @author <a href="mailto:ales.pucelj@cosylab.com">Ales Pucelj</a>
56   * @version $id$
57   */
58  public class DeviceCellRenderer extends DefaultTableCellRenderer
59  	implements TableCellEditor
60  {
61  	private static final long serialVersionUID = 1L;
62  	private static final Color SELECTED = Color.GREEN;
63  	private Color unselected;
64  	private CommandPopUp popup;
65  	private Logger logger = DebugLogger.getLogger("DevCellRen", Level.OFF);
66  
67  	class CommandPopUp extends JPopupMenu implements ActionListener
68  	{
69  		private static final long serialVersionUID = 1L;
70  		//private DeviceCell cell;
71  		private WeakReference<DeviceCell> ref;
72  		private boolean prepared = false;
73  
74  		DeviceCell getCell()
75  		{
76  			return (DeviceCell)ref.get();
77  		}
78  
79  		void setCell(DeviceCell cell)
80  		{
81  			if (ref!=null && ref.get() == cell) {
82  				return;
83  			}
84  
85  			ref= new WeakReference<DeviceCell>(cell);
86  			removeAll();
87  			prepared = false;
88  		}
89  
90  		/**
91  		 * Prepares menu.
92  		 */
93  		public void prepare()
94  		{
95  			if (prepared) {
96  				return;
97  			}
98  
99  			prepared = true;
100 			
101 			DeviceCell cell= getCell();
102 			if (cell==null) {
103 				return;
104 			}
105 
106 			JMenuItem item = new JMenuItem(cell.getIdentifier());
107 			item.setFont(item.getFont().deriveFont(Font.BOLD).deriveFont((float)(item.getFont()
108 			        .getSize() * 1.2)));
109 			item.setEnabled(false);
110 			add(item);
111 			add(new JSeparator(SwingConstants.HORIZONTAL));
112 
113 			Command[] c = cell.getCommands();
114 
115 			if (c == null) {
116 				return;
117 			}
118 
119 			for (int i = 0; i < c.length; i++) {
120 				JMenuItem jmi= new JMenuItem(c[i].getName());
121 				jmi.addActionListener(this);
122 				jmi.setActionCommand(c[i].getName());
123 				add(jmi);
124 			}
125 		}
126 		
127 		/* (non-Javadoc)
128 		 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
129 		 */
130 		public void actionPerformed(ActionEvent e) {
131 			
132 			DeviceCell cell=getCell();
133 			
134 			if (cell==null) {
135 				return;
136 			}
137 			Command[] c = cell.getCommands();
138 
139 			if (c == null) {
140 				return;
141 			}
142 			
143 			for (int i = 0; i < c.length; i++) {
144 				if (c[i].getName().equals(e.getActionCommand())) {
145 					try {
146 						c[i].execute(cell);
147 					} catch (Exception ex) {
148 						ex.printStackTrace();
149 					}
150 					return;
151 				}
152 			}
153 		}
154 	}
155 
156 	/**
157 	 * Constructs a new DeviceCellRenderer.
158 	 *
159 	 */
160 	public DeviceCellRenderer()
161 	{
162 		this(false,true);
163 	}
164 	
165 	/**
166 	 * Constructs a new DeviceCellRenderer.
167 	 * 
168 	 * @param decorateBorder if true decorated border will be used
169 	 * @param decorateBackground if true decorated background will be used
170 	 */
171 	public DeviceCellRenderer(boolean decorateBorder, boolean decorateBackground)
172 	{
173 		super(decorateBorder,decorateBackground);
174 		unselected = getBackground();
175 
176 		//setOpaque(true);
177 		popup = new CommandPopUp();
178 		addMouseListener(new MouseAdapter() {
179 				//private Point lastPoint;
180 
181 				/* (non-Javadoc)
182 				 * @see java.awt.event.MouseAdapter#mouseClicked(java.awt.event.MouseEvent)
183 				 */
184 				public void mouseClicked(MouseEvent e) {
185 					logger.finer("CLICK");
186 					popup.prepare();
187 					popup.show(DeviceCellRenderer.this, e.getX(), e.getY());
188 				}
189 				/**
190 				 * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
191 				 */
192 				public void mousePressed(MouseEvent e)
193 				{
194 //					lastPoint = e.getPoint();
195 					logger.finer("PRESS");
196 					popup.prepare();
197 					popup.show(DeviceCellRenderer.this, e.getX(), e.getY());
198 
199 					/*if (SwingUtilities.isRightMouseButton(e)) {
200 					    logger.finer("RIGTH");
201 					    lastPoint = e.getPoint();
202 					} else {
203 					    logger.finer("CLICK");
204 					    lastPoint = null;
205 					}*/
206 				}
207 
208 				/**
209 				 * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
210 				 */
211 				public void mouseReleased(MouseEvent e)
212 				{
213 					logger.finer("RELEASE");
214 					popup.prepare();
215 					popup.show(DeviceCellRenderer.this, e.getX(), e.getY());
216 /*
217 					//if (SwingUtilities.isRightMouseButton(e)) {
218 					if ((e.getSource() == DeviceCellRenderer.this)
219 					    && (lastPoint != null)) {
220 						logger.finer("POPUP");
221 						popup.prepare();
222 						popup.show(DeviceCellRenderer.this, e.getX(), e.getY());
223 					}
224 
225 					lastPoint = null;
226 */
227 					//}
228 				}
229 			});
230 	}
231 
232 	/*
233 	 * (non-Javadoc)
234 	 * @see com.cosylab.gui.components.table.renderers.DefaultTableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
235 	 */
236 	public Component getTableCellRendererComponent(JTable table,
237 	    Object propertyCell, boolean isSelected, boolean hasFocus, int row,
238 	    int column)
239 	{
240 		super.getTableCellRendererComponent(table, propertyCell, isSelected,
241 		    hasFocus, row, column);
242 
243 		if (propertyCell instanceof DeviceCell) {
244 			DeviceCell cellProperty = (DeviceCell)propertyCell;
245 			popup.setCell(cellProperty);
246 
247 			setFont(getFont().deriveFont(Font.BOLD));
248 			setText(cellProperty.getIdentifier());
249 			if (cellProperty.isHighlightCell()) {
250 				setBackground(SELECTED);
251 			} else {
252 				setBackground(unselected);
253 			}
254 			
255 			String t= cellProperty.getTooltip();
256 			if (t==null) {
257 				t=getText();
258 			}
259 			setToolTipText(t);
260 		}
261 
262 		logger.fine("RENDERER");
263 
264 		return this;
265 	}
266 
267 	/* (non-Javadoc)
268 	 * @see javax.swing.CellEditor#stopCellEditing()
269 	 */
270 	public boolean stopCellEditing()
271 	{
272 		fireCancel(new ChangeEvent(this));
273 
274 		return false;
275 	}
276 
277 	/*private void fireStop(ChangeEvent ev)
278 	{
279 		CellEditorListener[] l = (CellEditorListener[])listeners.toArray();
280 
281 		for (int i = 0; i < l.length; i++) {
282 			try {
283 				l[i].editingStopped(ev);
284 			} catch (Exception e) {
285 				e.printStackTrace();
286 			}
287 		}
288 	}*/
289 
290 	private void fireCancel(ChangeEvent ev)
291 	{
292 		CellEditorListener[] l = (CellEditorListener[])listeners.toArray();
293 
294 		for (int i = 0; i < l.length; i++) {
295 			try {
296 				l[i].editingCanceled(ev);
297 			} catch (Exception e) {
298 				e.printStackTrace();
299 			}
300 		}
301 	}
302 
303 	private ObjectList listeners = new ObjectList(CellEditorListener.class);
304 
305 	/* (non-Javadoc)
306 	 * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int)
307 	 */
308 	public Component getTableCellEditorComponent(JTable table, Object value,
309 	    boolean isSelected, int row, int column)
310 	{
311 		super.getTableCellRendererComponent(table, value, isSelected, true,
312 		    row, column);
313 
314 		if (value instanceof DeviceCell) {
315 			DeviceCell cellProperty = (DeviceCell)value;
316 			popup.setCell(cellProperty);
317 
318 			setFont(getFont().deriveFont(Font.BOLD));
319 			setText(cellProperty.getIdentifier());
320 			setBackground(SELECTED);
321 
322 			String t=cellProperty.getTooltip();
323 			if (t==null) {
324 			if (cellProperty.getCommands() != null
325 			    && cellProperty.getCommands().length > 0) {
326 				t="Click to send command";
327 			} else {
328 				t=getText();
329 			}}
330 			setToolTipText(t);
331 		}
332 
333 		logger.fine("EDITOR");
334 
335 		return this;
336 	}
337 
338 	/* (non-Javadoc)
339 	 * @see javax.swing.CellEditor#addCellEditorListener(javax.swing.event.CellEditorListener)
340 	 */
341 	public void addCellEditorListener(CellEditorListener l)
342 	{
343 		listeners.add(l);
344 	}
345 
346 	/* (non-Javadoc)
347 	 * @see javax.swing.CellEditor#cancelCellEditing()
348 	 */
349 	public void cancelCellEditing()
350 	{
351 		fireCancel(new ChangeEvent(this));
352 	}
353 
354 	/* (non-Javadoc)
355 	 * @see javax.swing.CellEditor#getCellEditorValue()
356 	 */
357 	public Object getCellEditorValue()
358 	{
359 		return null;
360 	}
361 
362 	/* (non-Javadoc)
363 	 * @see javax.swing.CellEditor#isCellEditable(java.util.EventObject)
364 	 */
365 	public boolean isCellEditable(EventObject anEvent)
366 	{
367 		if (anEvent instanceof MouseEvent) {
368 			Point p = ((MouseEvent)anEvent).getPoint();
369 			ObjectTable table = (ObjectTable)anEvent.getSource();
370 			int idx = table.rowAtPoint(p);
371 			return (idx == table.getSelectedRow());
372 		}
373 		return true;
374 	}
375 
376 	/* (non-Javadoc)
377 	 * @see javax.swing.CellEditor#removeCellEditorListener(javax.swing.event.CellEditorListener)
378 	 */
379 	public void removeCellEditorListener(CellEditorListener l)
380 	{
381 		listeners.remove(l);
382 	}
383 
384 	/* (non-Javadoc)
385 	 * @see javax.swing.CellEditor#shouldSelectCell(java.util.EventObject)
386 	 */
387 	public boolean shouldSelectCell(EventObject anEvent)
388 	{
389 		return true;
390 	}
391 	
392 }
393 
394 /* __oOo__ */