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