1 /*
2  * $Id: JTableRenderer.java,v 1.5 2012-01-13 11:04:36 david Exp $
3  * Copyright (c) 2001-2005, Gaudenz Alder
4  *
5  * All rights reserved.
6  *
7  * See LICENSE file for license details. If you are unable to locate
8  * this file please contact info (at) jgraph (dot) com.
9  */
10 package com.mxgraph.examples.swing.editor;
11 
12 import java.awt.BorderLayout;
13 import java.awt.Color;
14 import java.awt.Component;
15 import java.awt.Cursor;
16 import java.awt.Dimension;
17 import java.awt.FlowLayout;
18 import java.awt.Font;
19 import java.awt.Point;
20 import java.awt.datatransfer.Transferable;
21 import java.awt.dnd.DnDConstants;
22 import java.awt.dnd.DropTarget;
23 import java.awt.dnd.DropTargetDragEvent;
24 import java.awt.dnd.DropTargetDropEvent;
25 import java.awt.dnd.DropTargetEvent;
26 import java.awt.dnd.DropTargetListener;
27 import java.awt.event.ActionEvent;
28 import java.awt.event.AdjustmentEvent;
29 import java.awt.event.AdjustmentListener;
30 import java.awt.event.MouseEvent;
31 import java.awt.event.MouseListener;
32 import java.awt.event.MouseMotionListener;
33 
34 import javax.swing.AbstractAction;
35 import javax.swing.BorderFactory;
36 import javax.swing.ImageIcon;
37 import javax.swing.JButton;
38 import javax.swing.JComponent;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTable;
43 import javax.swing.SwingUtilities;
44 import javax.swing.TransferHandler;
45 import javax.swing.border.BevelBorder;
46 import javax.swing.table.AbstractTableModel;
47 import javax.swing.table.TableColumn;
48 import javax.swing.table.TableModel;
49 
50 import com.mxgraph.swing.mxGraphComponent;
51 import com.mxgraph.swing.handler.mxCellHandler;
52 import com.mxgraph.swing.handler.mxGraphTransferHandler;
53 import com.mxgraph.swing.util.mxGraphTransferable;
54 import com.mxgraph.view.mxGraph;
55 
56 /**
57  * @author Administrator
58  *
59  */
60 public class JTableRenderer extends JComponent
61 {
62 
63 	/**
64 	 *
65 	 */
66 	private static final long serialVersionUID = 2106746763664760745L;
67 
68 	/**
69 	 *
70 	 */
71 	public static final String IMAGE_PATH = "/com/mxgraph/examples/swing/images/";
72 
73 	/**
74 	 *
75 	 */
76 	protected static JTableRenderer dragSource = null;
77 
78 	/**
79 	 *
80 	 */
81 	protected static int sourceRow = 0;
82 
83 	/**
84 	 *
85 	 */
86 	protected Object cell;
87 
88 	/**
89 	 *
90 	 */
91 	protected mxGraphComponent graphContainer;
92 
93 	/**
94 	 *
95 	 */
96 	protected mxGraph graph;
97 
98 	/**
99 	 *
100 	 */
101 	public JTable table;
102 
103 	/**
104 	 *
105 	 */
106 	@SuppressWarnings("serial")
JTableRenderer(final Object cell, final mxGraphComponent graphContainer)107 	public JTableRenderer(final Object cell,
108 			final mxGraphComponent graphContainer)
109 	{
110 		this.cell = cell;
111 		this.graphContainer = graphContainer;
112 		this.graph = graphContainer.getGraph();
113 		setLayout(new BorderLayout());
114 		setBorder(BorderFactory.createCompoundBorder(ShadowBorder
115 				.getSharedInstance(), BorderFactory
116 				.createBevelBorder(BevelBorder.RAISED)));
117 
118 		JPanel title = new JPanel();
119 		title.setBackground(new Color(149, 173, 239));
120 		title.setOpaque(true);
121 		title.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 1));
122 		title.setLayout(new BorderLayout());
123 
124 		JLabel icon = new JLabel(new ImageIcon(JTableRenderer.class
125 				.getResource(IMAGE_PATH + "preferences.gif")));
126 		icon.setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 1));
127 		title.add(icon, BorderLayout.WEST);
128 
129 		JLabel label = new JLabel(String.valueOf(graph.getLabel(cell)));
130 		label.setForeground(Color.WHITE);
131 		label.setFont(title.getFont().deriveFont(Font.BOLD, 11));
132 		label.setBorder(BorderFactory.createEmptyBorder(0, 1, 0, 2));
133 		title.add(label, BorderLayout.CENTER);
134 
135 		JPanel toolBar2 = new JPanel();
136 		toolBar2.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 2));
137 		toolBar2.setOpaque(false);
138 		JButton button = new JButton(new AbstractAction("", new ImageIcon(
139 				JTableRenderer.class.getResource(IMAGE_PATH + "minimize.gif")))
140 		{
141 
142 			public void actionPerformed(ActionEvent e)
143 			{
144 				graph.foldCells(graph.isCellCollapsed(cell), false,
145 						new Object[] { cell });
146 				((JButton) e.getSource())
147 						.setIcon(new ImageIcon(
148 								JTableRenderer.class
149 										.getResource(IMAGE_PATH
150 												+ ((graph.isCellCollapsed(cell)) ? "maximize.gif"
151 														: "minimize.gif"))));
152 			}
153 		});
154 		button.setPreferredSize(new Dimension(16, 16));
155 		button.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
156 		button.setToolTipText("Collapse/Expand");
157 		button.setOpaque(false);
158 		toolBar2.add(button);
159 
160 		title.add(toolBar2, BorderLayout.EAST);
161 		add(title, BorderLayout.NORTH);
162 
163 		// CellStyle style =
164 		// graph.getStylesheet().getCellStyle(graph.getModel(),
165 		// cell);
166 		// if (style.getStyleClass() == null) {
167 		table = new MyTable();
168 		JScrollPane scrollPane = new JScrollPane(table);
169 		scrollPane.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
170 
171 		if (graph.getModel().getChildCount(cell) == 0)
172 		{
173 			scrollPane.getViewport().setBackground(Color.WHITE);
174 			setOpaque(true);
175 			add(scrollPane, BorderLayout.CENTER);
176 		}
177 
178 		scrollPane.getVerticalScrollBar().addAdjustmentListener(
179 				new AdjustmentListener()
180 				{
181 
182 					public void adjustmentValueChanged(AdjustmentEvent e)
183 					{
184 						graphContainer.refresh();
185 					}
186 
187 				});
188 
189 		label = new JLabel(new ImageIcon(JTableRenderer.class
190 				.getResource(IMAGE_PATH + "resize.gif")));
191 		label.setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
192 
193 		JPanel panel = new JPanel();
194 		panel.setLayout(new BorderLayout());
195 		panel.add(label, BorderLayout.EAST);
196 
197 		add(panel, BorderLayout.SOUTH);
198 
199 		ResizeHandler resizeHandler = new ResizeHandler();
200 		label.addMouseListener(resizeHandler);
201 		label.addMouseMotionListener(resizeHandler);
202 
203 		setMinimumSize(new Dimension(20, 30));
204 	}
205 
206 	/**
207 	 * Implements an event redirector for the specified handle index, where 0
208 	 * is the top right, and 1-7 are the top center, rop right, middle left,
209 	 * middle right, bottom left, bottom center and bottom right, respectively.
210 	 * Default index is 7 (bottom right).
211 	 */
212 	public class ResizeHandler implements MouseListener, MouseMotionListener
213 	{
214 
215 		protected int index;
216 
ResizeHandler()217 		public ResizeHandler()
218 		{
219 			this(7);
220 		}
221 
ResizeHandler(int index)222 		public ResizeHandler(int index)
223 		{
224 			this.index = index;
225 		}
226 
mouseClicked(MouseEvent e)227 		public void mouseClicked(MouseEvent e)
228 		{
229 			// ignore
230 		}
231 
mouseEntered(MouseEvent e)232 		public void mouseEntered(MouseEvent e)
233 		{
234 			// ignore
235 		}
236 
mouseExited(MouseEvent e)237 		public void mouseExited(MouseEvent e)
238 		{
239 			// ignore
240 		}
241 
mousePressed(MouseEvent e)242 		public void mousePressed(MouseEvent e)
243 		{
244 			// Selects to create a handler for resizing
245 			if (!graph.isCellSelected(cell))
246 			{
247 				graphContainer.selectCellForEvent(cell, e);
248 			}
249 
250 			// Initiates a resize event in the handler
251 			mxCellHandler handler = graphContainer.getSelectionCellsHandler().getHandler(
252 					cell);
253 
254 			if (handler != null)
255 			{
256 				// Starts the resize at index 7 (bottom right)
257 				handler.start(SwingUtilities.convertMouseEvent((Component) e
258 						.getSource(), e, graphContainer.getGraphControl()),
259 						index);
260 				e.consume();
261 			}
262 		}
263 
mouseReleased(MouseEvent e)264 		public void mouseReleased(MouseEvent e)
265 		{
266 			graphContainer.getGraphControl().dispatchEvent(
267 					SwingUtilities.convertMouseEvent((Component) e.getSource(),
268 							e, graphContainer.getGraphControl()));
269 		}
270 
mouseDragged(MouseEvent e)271 		public void mouseDragged(MouseEvent e)
272 		{
273 			graphContainer.getGraphControl().dispatchEvent(
274 					SwingUtilities.convertMouseEvent((Component) e.getSource(),
275 							e, graphContainer.getGraphControl()));
276 		}
277 
mouseMoved(MouseEvent e)278 		public void mouseMoved(MouseEvent e)
279 		{
280 			// ignore
281 		}
282 	}
283 
284 	/**
285 	 *
286 	 */
287 	public class MyTable extends JTable implements DropTargetListener
288 	{
289 
290 		/**
291 		 *
292 		 */
293 		private static final long serialVersionUID = 5841175227984561071L;
294 
295 		Object[][] data;
296 
297 		String[] colNames = new String[] { "A", "B", "C", "D", "E" };
298 
299 		@SuppressWarnings("serial")
MyTable()300 		public MyTable()
301 		{
302 			data = new Object[30][5];
303 			for (int i = 0; i < 30; i++)
304 			{
305 				data[i][0] = new Boolean(false);
306 				data[i][1] = "Column " + i;
307 				data[i][2] = (Math.random() > 0.5) ? new ImageIcon(
308 						JTableRenderer.class.getResource(IMAGE_PATH
309 								+ "preferences.gif")) : null;
310 				data[i][3] = (Math.random() > 0.5) ? new ImageIcon(
311 						JTableRenderer.class.getResource(IMAGE_PATH
312 								+ "preferences.gif")) : null;
313 				data[i][4] = (Math.random() > 0.5) ? new ImageIcon(
314 						JTableRenderer.class.getResource(IMAGE_PATH
315 								+ "preferences.gif")) : null;
316 			}
317 			setModel(createModel());
318 			setTableHeader(null);
319 			setAutoscrolls(true);
320 			setGridColor(Color.WHITE);
321 			TableColumn column = getColumnModel().getColumn(0);
322 			column.setMaxWidth(20);
323 			column = getColumnModel().getColumn(2);
324 			column.setMaxWidth(12);
325 			column = getColumnModel().getColumn(3);
326 			column.setMaxWidth(12);
327 			column = getColumnModel().getColumn(4);
328 			column.setMaxWidth(12);
329 
330 			setTransferHandler(new TransferHandler()
331 			{
332 
333 				/* (non-Javadoc)
334 				 * @see javax.swing.TransferHandler#getSourceActions(javax.swing.JComponent)
335 				 */
336 				@Override
337 				public int getSourceActions(JComponent c)
338 				{
339 					return COPY_OR_MOVE;
340 				}
341 
342 				/*
343 				 * (non-Javadoc)
344 				 *
345 				 * @see javax.swing.TransferHandler#createTransferable(javax.swing.JComponent)
346 				 */
347 				protected Transferable createTransferable(JComponent c)
348 				{
349 					sourceRow = getSelectedRow();
350 					dragSource = JTableRenderer.this;
351 					//mxRectangle bounds = new mxRectangle(0, 0, MyTable.this
352 					//		.getWidth(), 20);
353 					return new mxGraphTransferable(null, null, null);
354 				}
355 
356 			});
357 
358 			setDragEnabled(true);
359 			setDropTarget(new DropTarget(this, // component
360 					DnDConstants.ACTION_COPY_OR_MOVE, // actions
361 					this));
362 			setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
363 		}
364 
365 		/**
366 		 *
367 		 */
getDropTarget()368 		public DropTarget getDropTarget()
369 		{
370 			if (!((mxGraphTransferHandler) graphContainer.getTransferHandler())
371 					.isLocalDrag())
372 			{
373 				return super.getDropTarget();
374 			}
375 
376 			return null;
377 		}
378 
379 		/*
380 		 * (non-Javadoc)
381 		 *
382 		 * @see java.awt.dnd.DropTargetListener#dragEnter(java.awt.dnd.DropTargetDragEvent)
383 		 */
dragEnter(DropTargetDragEvent e)384 		public void dragEnter(DropTargetDragEvent e)
385 		{
386 
387 		}
388 
389 		/*
390 		 * (non-Javadoc)
391 		 *
392 		 * @see java.awt.dnd.DropTargetListener#dragOver(java.awt.dnd.DropTargetDragEvent)
393 		 */
dragOver(DropTargetDragEvent e)394 		public void dragOver(DropTargetDragEvent e)
395 		{
396 			if (!((mxGraphTransferHandler) graphContainer.getTransferHandler())
397 					.isLocalDrag()
398 					&& JTableRenderer.this != dragSource)
399 			{
400 				Point p = e.getLocation();
401 				int row = rowAtPoint(p);
402 				getSelectionModel().setSelectionInterval(row, row);
403 			}
404 		}
405 
406 		/*
407 		 * (non-Javadoc)
408 		 *
409 		 * @see java.awt.dnd.DropTargetListener#dropActionChanged(java.awt.dnd.DropTargetDragEvent)
410 		 */
dropActionChanged(DropTargetDragEvent dtde)411 		public void dropActionChanged(DropTargetDragEvent dtde)
412 		{
413 			// TODO Auto-generated method stub
414 
415 		}
416 
417 		/*
418 		 * (non-Javadoc)
419 		 *
420 		 * @see java.awt.dnd.DropTargetListener#drop(java.awt.dnd.DropTargetDropEvent)
421 		 */
drop(DropTargetDropEvent e)422 		public void drop(DropTargetDropEvent e)
423 		{
424 			if (dragSource != null)
425 			{
426 				e.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
427 				Point p = e.getLocation();
428 				int targetRow = rowAtPoint(p);
429 
430 				Object edge = graph.insertEdge(null, null, null,
431 						dragSource.cell, JTableRenderer.this.cell, "sourceRow="
432 								+ sourceRow + ";targetRow=" + targetRow);
433 				graph.setSelectionCell(edge);
434 
435 				// System.out.println("clearing drag source");
436 				dragSource = null;
437 				e.dropComplete(true);
438 			}
439 			else
440 			{
441 				e.rejectDrop();
442 			}
443 		}
444 
445 		/*
446 		 * (non-Javadoc)
447 		 *
448 		 * @see java.awt.dnd.DropTargetListener#dragExit(java.awt.dnd.DropTargetEvent)
449 		 */
dragExit(DropTargetEvent dte)450 		public void dragExit(DropTargetEvent dte)
451 		{
452 			// TODO Auto-generated method stub
453 
454 		}
455 
456 		/**
457 		 *
458 		 * @return the created table model
459 		 */
createModel()460 		public TableModel createModel()
461 		{
462 			return new AbstractTableModel()
463 			{
464 
465 				/**
466 				 *
467 				 */
468 				private static final long serialVersionUID = -3642207266816170738L;
469 
470 				public int getColumnCount()
471 				{
472 					return colNames.length;
473 				}
474 
475 				public int getRowCount()
476 				{
477 					return data.length;
478 				}
479 
480 				public String getColumnName(int col)
481 				{
482 					return colNames[col];
483 				}
484 
485 				public Object getValueAt(int row, int col)
486 				{
487 					return data[row][col];
488 				}
489 
490 				public Class<? extends Object> getColumnClass(int c)
491 				{
492 					Object value = getValueAt(0, c);
493 					return (value != null) ? value.getClass() : ImageIcon.class;
494 				}
495 
496 				/*
497 				 * Don't need to implement this method unless your table's
498 				 * editable.
499 				 */
500 				public boolean isCellEditable(int row, int col)
501 				{
502 					return col == 0;
503 				}
504 
505 				/*
506 				 * Don't need to implement this method unless your table's data
507 				 * can change.
508 				 */
509 				public void setValueAt(Object value, int row, int col)
510 				{
511 					data[row][col] = value;
512 					fireTableCellUpdated(row, col);
513 				}
514 			};
515 
516 		}
517 
518 	}
519 
520 	/**
521 	 *
522 	 */
getVertex(Component component)523 	public static JTableRenderer getVertex(Component component)
524 	{
525 		while (component != null)
526 		{
527 			if (component instanceof JTableRenderer)
528 			{
529 				return (JTableRenderer) component;
530 			}
531 			component = component.getParent();
532 		}
533 
534 		return null;
535 	}
536 
537 }
538