Squiz Matrix  4.12.2
 All Data Structures Namespaces Functions Variables Pages
InspectorGadget.java
1 
21 package net.squiz.matrix.inspector;
22 
23 import net.squiz.matrix.core.*;
24 import net.squiz.matrix.matrixtree.*;
25 import net.squiz.matrix.ui.*;
26 
27 import java.util.*;
28 import org.w3c.dom.*;
29 import java.io.IOException;
30 
31 import java.awt.*;
32 import java.awt.dnd.*;
33 import java.awt.datatransfer.*;
34 import java.awt.event.*;
35 import java.awt.image.*;
36 import java.awt.geom.*;
37 
38 import javax.swing.*;
39 import javax.swing.event.*;
40 import javax.swing.table.*;
41 import javax.swing.tree.*;
42 import javax.swing.plaf.*;
43 
44 
50 public class InspectorGadget extends JTable
51  implements MouseListener,
52  ComponentListener,
53  NodeDoubleClickedListener,
55  InitialisationListener,
56  Autoscroll,
57  Scrollable {
58 
59  private int columns;
60  private java.util.List filters = new Vector();
61  private MatrixTree tree;
62  private InspectorNavigator navigator;
63  private TreePath currentPath;
64 
65  private SelectionTool selTool;
66  private DragHandler dragHandler;
67  private DropHandler dropHandler;
68  private MenuHandler menuHandler;
69  private DragSource dragSource = null;
70 
71  private int lastRowOver = -1;
72  private static final int AUTOSCROLL_MARGIN = 12;
73 
74  private static final int CUE_LEFT = 0;
75  private static final int CUE_RIGHT = 1;
76 
77  protected BufferedImage dblBuffer = null;
78 
79  //{{{ Public Methods
80 
88  public InspectorGadget(TableModel model, MatrixTree tree) {
89  super(model);
90  // filters.add(new TypeCodeFilter("page_standard"));
91  addMouseListener(this);
92  setCellEditor(null);
93  setTableHeader(null);
94 
95  this.tree = tree;
96  // we want to listen to the tree model updates
97  tree.getModel().addTreeModelListener(getInspectorTreeModelListener());
98 
99  //currentPath = tree.getPathToRoot(AssetManager.getRootFolderNode());
100 
101  navigator = new InspectorNavigator(this);
102  selTool = new SelectionTool((JTable)this);
103  dragHandler = getDragHandler();
104  dropHandler = getDropHandler();
105  menuHandler = getMenuHandler();
106 
107  addMouseListener(selTool);
108  addMouseListener(menuHandler);
109  addMouseMotionListener(selTool);
110 
111  dragSource = DragSource.getDefaultDragSource();
112 
113  DragGestureRecognizer dgr =
114  dragSource.createDefaultDragGestureRecognizer(
115  this, //DragSource
116  DnDConstants.ACTION_COPY_OR_MOVE, //specifies valid actions
117  dragHandler //DragGestureListener
118  );
119 
120  dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK);
121  DropTarget dropTarget = new DropTarget(this, dropHandler);
122 
123  AssetManager.addInitialisationListener(this);
124 
125  setUI(new MatrixTableUI());
126 
127  // create a mouse motion listener to update the ViewPort when we
128  // do a drag operation where the drag extends greater than the tree size
129  /*MouseMotionListener mmListener = new MouseMotionAdapter() {
130  public void mouseDragged(MouseEvent evt) {
131  Point pt = evt.getPoint();
132 
133  int row = rowAtPoint(pt);
134 
135  if (row == getRowCount() - 1)
136  return;
137 
138  Rectangle bounds = getBounds();
139 
140  if (pt.y + bounds.y <= AUTOSCROLL_MARGIN) {
141  if (row > 0) --row;
142  }
143  else {
144  if (row < getRowCount() - 1) ++row;
145  }
146  scrollRectToVisible(getCellRect(row, 0, true));
147 
148  //Rectangle r = new Rectangle(evt.getX(), evt.getY(), 6, 6);
149  //scrollRectToVisible(r);
150  }
151  };*/
152  setAutoscrolls(false);
153  //addMouseMotionListener(mmListener);
154  }
155 
161  public InspectorNavigator getNavigator() {
162  return navigator;
163  }
164 
170  public MatrixTree getTree() {
171  return tree;
172  }
173 
174  public void autoscroll(Point pt) {
175  int row = rowAtPoint(pt);
176  Rectangle bounds = getBounds();
177 
178  if (pt.y + bounds.y <= AUTOSCROLL_MARGIN) {
179  if (row > 0) --row;
180  }
181  else {
182  if (row < getRowCount() - 1) ++row;
183  }
184  scrollRectToVisible(getCellRect(row, 0, true));
185  }
186 
187  public Insets getAutoscrollInsets() {
188  Rectangle outer = getBounds();
189  Rectangle inner = getParent().getBounds();
190  return new Insets( inner.y - outer.y + AUTOSCROLL_MARGIN,
191  inner.x - outer.x + AUTOSCROLL_MARGIN,
192  outer.height - inner.height - inner.y + outer.y + AUTOSCROLL_MARGIN,
193  outer.width - inner.width - inner.x + outer.x + AUTOSCROLL_MARGIN);
194  }
195 
202  listenerList.add(TransferListener.class, l);
203  }
204 
211  listenerList.remove(TransferListener.class, l);
212  }
213 
222  int row = getSelectedRow();
223  int col = getSelectedColumn();
224 
225  if (isCellSelected(row,col)) {
226  return new NodePosition(row,col);
227  }
228  return null;
229  }
230 
239  // Get the min and max ranges of selected cells
240  int rowIndexStart = getSelectedRow();
241  int rowIndexEnd = getSelectionModel().getMaxSelectionIndex();
242  int colIndexStart = getSelectedColumn();
243  int colIndexEnd = getColumnModel().getSelectionModel().getMaxSelectionIndex();
244 
245  // MM: what happens if there is no selection?
246 
247  // Check each cell in the range
248  ArrayList nodes = new ArrayList();
249 
250  for (int row = 0; row <= getRowCount(); row++) {
251  for (int col = 0; col <= getColumnCount(); col++) {
252  if (isCellSelected(row, col)) {
253  nodes.add( new NodePosition(row,col) );
254  }
255  }
256  }
257 
258  return (NodePosition[]) nodes.toArray(new NodePosition[nodes.size()]);
259  }
260 
267  NodePosition topMost = positions[0];
268 
269  for (int i = 0; i < positions.length; i++){
270  if (positions[i].getRow() < topMost.getRow())
271  topMost = positions[i];
272  }
273  return topMost;
274  }
275 
282  NodePosition bottomMost = positions[0];
283 
284  for (int i = 0; i < positions.length; i++){
285  if (positions[i].getRow() > bottomMost.getRow())
286  bottomMost = positions[i];
287  }
288  return bottomMost;
289  }
290 
297  NodePosition leftMost = positions[0];
298 
299  for (int i = 0; i < positions.length; i++){
300  if (positions[i].getColumn() < leftMost.getColumn())
301  leftMost = positions[i];
302  }
303  return leftMost;
304  }
305 
312  NodePosition rightMost = positions[0];
313 
314  for (int i = 0; i < positions.length; i++){
315  if (positions[i].getColumn() > rightMost.getColumn())
316  rightMost = positions[i];
317  }
318  return rightMost;
319  }
320 
327  public TreePath[] getSelectionPaths() {
328  NodePosition[] nodes = getSelectionNodes();
329  TreePath[] paths = new TreePath[nodes.length];
330 
331  for (int i = 0; i < nodes.length; i++) {
332  MatrixTreeNode node = (MatrixTreeNode) getValueAt(nodes[i].getRow(), nodes[i].getColumn());
333  paths[i] = tree.getPathToRoot(node);
334  }
335  return paths;
336  }
337 
338  public TreePath getSelectionPath() {
340  MatrixTreeNode node = (MatrixTreeNode) getValueAt(pos.getRow(), pos.getColumn());
341  return tree.getPathToRoot(node);
342  }
343 
350  public Rectangle getSelectionBounds(NodePosition[] positions)
351  {
352  NodePosition topMost = getTopMostSelection(positions);
353  NodePosition bottomMost = getBottomMostSelection(positions);
354  NodePosition leftMost = getLeftMostSelection(positions);
355  NodePosition rightMost = getRightMostSelection(positions);
356 
357  int topX = (int) getCellRect(leftMost.getRow(),leftMost.getColumn(),true).getX();
358  int topY = (int) getCellRect(topMost.getRow(),topMost.getColumn(),true).getY();
359 
360  int bottomX = (int) getCellRect(rightMost.getRow(),rightMost.getColumn(),true).getX();
361  bottomX += (int) getCellRect(rightMost.getRow(),rightMost.getColumn(),true).getWidth();
362 
363  int bottomY = (int) getCellRect(bottomMost.getRow(),bottomMost.getColumn(),true).getY();
364  bottomY += (int) getCellRect(bottomMost.getRow(),bottomMost.getColumn(),true).getHeight();
365 
366  return new Rectangle(topX, topY, bottomX - topX, bottomY - topY);
367  }
368 
375  for (int i = getColumnCount() - 1; i >= 0; i--) {
376  if (getValueAt(getRowCount() - 1, i) != null)
377  return new NodePosition(getRowCount() - 1, i);
378  }
379  return null;
380  }
381 
387  public void populateInspector(TreePath path) {
388  MatrixTreeNode parent = (MatrixTreeNode) path.getLastPathComponent();
389  Enumeration children = parent.children();
390  int childCount = parent.getChildCount();
391 
392  columns = Math.round(getWidth() / 70);
393 
394  // MM: fix this
395  if (columns == 0)
396  columns = 3;
397 
398  DefaultTableModel model = new InspectorTableModel(0,columns);
399 
400  MatrixTreeNode[] row = new MatrixTreeNode[columns];
401 
402  int allowedNodes = 0;
403  int i = 0;
404  boolean rowAdded = false;
405 
406  while (children.hasMoreElements()) {
407  MatrixTreeNode child = (MatrixTreeNode) children.nextElement();
408 
409  if (filtersAllowNode(child)) {
410  row[i] = child;
411  i++;
412  allowedNodes++;
413  rowAdded = false;
414  }
415 
416  if (i == columns) {
417  rowAdded = true;
418  model.addRow(row);
419  row = new MatrixTreeNode[columns];
420  i = 0;
421  }
422  }
423  if (!rowAdded && i > 0)
424  model.addRow(row);
425 
426  setModel(model);
427  }
428 
433  public void redrawInspector() {
434 
435  if (Math.round(getWidth()) / 70 == columns)
436  return;
437 
438  columns = Math.round(getWidth()) / 70;
439 
440  DefaultTableModel oldModel = (DefaultTableModel) getModel();
441  DefaultTableModel model = new InspectorTableModel(0,columns);
442 
443  MatrixTreeNode[] nodes = new MatrixTreeNode[oldModel.getRowCount() * oldModel.getColumnCount()];
444  MatrixTreeNode[] row = new MatrixTreeNode[columns];
445 
446  int a = 0;
447  for (int b = 0; b < oldModel.getRowCount(); b++) {
448  for (int c = 0; c < oldModel.getColumnCount(); c++) {
449  MatrixTreeNode node = (MatrixTreeNode) oldModel.getValueAt(b,c);
450  if (node != null) {
451  nodes[a] = node;
452  a++;
453  }
454  }
455  }
456 
457  int i = 0;
458  boolean rowAdded = false;
459  for (int j = 0; j < nodes.length; j++) {
460  // Add all the nodes from nodes[] to the new table.
461  MatrixTreeNode node = (MatrixTreeNode) nodes[j];
462 
463  row[i] = node;
464  i++;
465  rowAdded = false;
466 
467  if (i == columns) {
468  rowAdded = true;
469  model.addRow(row);
470  row = new MatrixTreeNode[columns];
471  i = 0;
472  }
473  }
474  if (!rowAdded && i > 0)
475  model.addRow(row);
476  setModel(model);
477  }
478 
479  /* MouseListener methods */
480 
487  public void mouseEntered(MouseEvent evt) {}
488 
495  public void mouseExited(MouseEvent evt) {}
496 
503  public void mouseReleased(MouseEvent evt) {}
504 
511  public void mousePressed(MouseEvent evt) {}
512 
520  public void mouseClicked(MouseEvent evt) {
521 
522  // we dont want to drill down the asset on right mouse clicks
523  if (GUIUtilities.isRightMouseButton(evt))
524  return;
525 
526  if (evt.getClickCount() != 2)
527  return;
528 
529  if (getSelectedColumn() == -1)
530  return;
531 
532  final MatrixTreeNode node = (MatrixTreeNode) getValueAt(getSelectedRow(), getSelectedColumn());
533 
534  if (node.getAsset().getNumKids() == 0)
535  return;
536 
537  // The selected cell is null (remainder cell on the end of a row), so return
538  if (node == null) {
539  return;
540  }
541 
542  if (!node.getAsset().childrenLoaded()) {
543  MatrixStatusBar.setStatus("Loading children...");
544  MatrixSwingWorker worker = new MatrixSwingWorker() {
545  public Object construct() {
546  try {
547  AssetManager.refreshAsset(node, "");
548  } catch (IOException ioe) {
549  ioe.printStackTrace();
550  }
551  MatrixStatusBar.setStatusAndClear("Success!", 1000);
552  TreePath path = tree.getPathToRoot(node);
553  populateInspector(path);
554  navigator.setBackPath(path);
555  return null;
556  }
557  };
558  worker.start();
559  } else {
560  TreePath path = tree.getPathToRoot(node);
561  populateInspector(path);
562  navigator.setBackPath(path);
563  }
564  }
565 
566  /* ComponentListener methods */
567 
574  public void componentHidden(ComponentEvent e) {}
575 
582  public void componentMoved(ComponentEvent e) {}
583 
590  public void componentShown(ComponentEvent e) {}
591 
598  public void componentResized(ComponentEvent e) {
599  redrawInspector();
600  }
601 
611  public void fireTransfer( int dragIndex,
612  int dropIndex,
613  MatrixTreeNode node,
614  MatrixTreeNode dropParent) {
615  // Guaranteed to return a non-null array
616  Object[] listeners = listenerList.getListenerList();
617  TransferEvent evt = null;
618 
619  // Process the listeners last to first, notifying
620  // those that are interested in this event
621  for (int i = listeners.length - 2; i >= 0; i -= 2) {
622  if (listeners[i] == TransferListener.class) {
623  // Lazily create the event:
624  if (evt == null) {
625  evt = new TransferEvent(this, dragIndex, dropIndex, node, dropParent);
626  }
627  ((TransferListener) listeners[i + 1]).transferGestureRecognized(evt);
628  }
629  }
630  }
631 
639  public void nodeDoubleClicked(NodeDoubleClickedEvent e) {
640  populateInspector(e.getClickedPath());
641  navigator.setBackPath(e.getClickedPath());
642  currentPath = e.getClickedPath();
643  }
644 
653 
654  //MM: we need to move all this stuff with the communication into one
655  // generic place so its transparent to the tree and inspector
656  tree.fireCreateLink(NewLinkEvent.LINK_TYPE_MOVE, new MatrixTreeNode [] { evt.getNode() }, evt.getDropParent(), evt.getDropIndex());
657  }
658 
666  public void initialisationComplete(InitialisationEvent e) {
667  currentPath = tree.getPathToRoot(e.getRootNode());
668  navigator.setCurrentPath(currentPath);
669  populateInspector(currentPath);
670  }
671 
680  public boolean mouseInsideCellComponent(Point point) {
681  int row = rowAtPoint(point);
682  int col = columnAtPoint(point);
683  TableCellRenderer renderer = getCellRenderer(row,col);
684  JLabel label = (JLabel) renderer.getTableCellRendererComponent(this,getValueAt(row,col),true,true,row,col);
685 
686  if (label == null)
687  return false;
688 
689  Dimension dim = label.getPreferredSize();
690 
691  Rectangle cellRect = getCellRect(row,col,true);
692 
693  // ICON STUFF //
694  int iconX = (int)( ( cellRect.getWidth() - label.getIcon().getIconWidth() ) / 2 + cellRect.getX() );
695  int iconY = (int)( ( cellRect.getHeight() - dim.getHeight() ) / 2 + cellRect.getY() );
696 
697  Rectangle iconRect = new Rectangle(iconX, iconY, label.getIcon().getIconWidth(), label.getIcon().getIconHeight());
698 
699  if (iconRect.contains(point))
700  return true;
701  // END ICON STUFF //
702 
703 
704  // TEXT STUFF //
705  int textWidth;
706  int textHeight;
707 
708  if (dim.getWidth() > cellRect.getWidth())
709  textWidth = (int) cellRect.getWidth();
710  else
711  textWidth = (int) dim.getWidth();
712 
713  // Override the above with a quick fix so that textWidth is the width of the cell
714  //textWidth = (int) cellRect.getWidth();
715 
716  textHeight = (int)( dim.getHeight() - label.getIcon().getIconHeight() + label.getIconTextGap() );
717 
718  int textX = (int)( ( cellRect.getWidth() - textWidth ) / 2 + cellRect.getX() );
719  int textY = (int)( iconRect.getY() + iconRect.getHeight() - label.getIconTextGap() );
720 
721  Rectangle textRect = new Rectangle(textX, textY, textWidth, textHeight);
722 
723  if (textRect.contains(point))
724  return true;
725  // END TEXT STUFF //
726 
727  return false;
728  }
729 
736  public void paintComponent(Graphics g) {
737  Graphics2D g2 = (Graphics2D) g;
738 
739  // this gets executed once
740  if (dblBuffer == null) {
741  initBufferImage();
742  }
743  g2.drawImage(dblBuffer, null, 0, 0);
744  super.paintComponent(g);
745 
746  if (selTool.isDragging())
747  selTool.paintSelectionTool(g2);
748  else if (dropHandler.isDropping()) {
749  dropHandler.paintDropImage(g2);
750  dropHandler.paintCueLine(g2);
751  }
752  }
753 
754  //}}}
755 
756  //{{{ Protected Methods
757 
764  protected boolean filtersAllowNode(MatrixTreeNode node) {
765  Iterator filterIterator = filters.iterator();
766  while (filterIterator.hasNext()) {
767  Filter filter = (Filter) filterIterator.next();
768  if (!filter.allowsNode(node))
769  return false;
770  }
771  return true;
772  }
773 
780  return new DragHandler();
781  }
782 
789  return new DropHandler();
790  }
791 
792  protected MenuHandler getMenuHandler() {
793  return new MenuHandler();
794  }
795 
796  protected InspectorTreeModelListener getInspectorTreeModelListener() {
797  return new InspectorTreeModelListener();
798  }
799 
808  protected Image getGhostedNode(NodePosition position) {
809  Component c = getComponentForPosition(position);
810  if (c == null)
811  return null;
812 
813  Rectangle bounds = getCellRect(position.getRow(), position.getColumn(), true);
814  // need to set the size of the component
815  c.setSize(bounds.width, bounds.height);
816 
817  BufferedImage image = new BufferedImage(
818  bounds.width,
819  bounds.height,
820  BufferedImage.TYPE_INT_ARGB_PRE
821  );
822 
823  Graphics2D g2d = (Graphics2D) image.createGraphics();
824  g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 0.9f));
825  c.paint(g2d);
826  g2d.dispose();
827 
828  return image;
829  }
830 
838  protected Image getGhostedNode(NodePosition[] positions) {
839 
840  Rectangle bounds = getSelectionBounds(positions);
841 
842  BufferedImage image = new BufferedImage((int) bounds.getWidth(), (int) bounds.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
843 
844  Graphics2D g2d = (Graphics2D) image.createGraphics();
845 
846  int widthOffset = 0;
847  int heightOffset = 0;
848 
849  NodePosition topMost = getTopMostSelection(positions);
850  NodePosition leftMost = getLeftMostSelection(positions);
851 
852  if (leftMost.getColumn() != 0)
853  widthOffset = leftMost.getColumn() * ((int) getCellRect(leftMost.getRow(), leftMost.getColumn(),true).getWidth());
854 
855  if (topMost.getRow() != 0)
856  heightOffset = topMost.getRow() * ((int) getCellRect(topMost.getRow(), topMost.getColumn(),true).getHeight());
857 
858  for (int i = 0; i < positions.length; i++) {
859  if (getValueAt(positions[i].getRow(), positions[i].getColumn()) != null) {
860  Image nodeImage = getGhostedNode(positions[i]);
861  Rectangle nodeBounds = getCellRect( positions[i].getRow(), positions[i].getColumn(), true );
862  g2d.drawImage(nodeImage, nodeBounds.x - widthOffset, nodeBounds.y - heightOffset, null);
863  }
864  }
865 
866  /*////IMAGE TESTER////
867  ImageIcon imageIcon = new ImageIcon(image);
868  JFrame testFrame = new JFrame();
869  JLabel label = new JLabel( imageIcon );
870  testFrame.getContentPane().add(label);
871  testFrame.setSize(400,400);
872  testFrame.setVisible(true);
873  g2d.setColor(Color.BLUE);
874  g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
875  g2d.fillRect(0,0, imageIcon.getIconWidth(), imageIcon.getIconHeight());
876  g2d.setColor(Color.BLUE.darker());
877  g2d.drawRect(0,0, imageIcon.getIconWidth() - 1, imageIcon.getIconHeight() - 1);
879 
880  g2d.dispose();
881 
882  return image;
883  }
884 
893  protected Image getDragImageForPosition(NodePosition[] positions) {
894  if (positions == null)
895  throw new IllegalArgumentException("positions is null");
896  Image ghostedImage = (positions.length == 1)
897  ? getGhostedNode(positions[0])
898  : getGhostedNode(positions);
899 
900  return ghostedImage;
901  }
902 
910  protected Component getComponentForPosition(NodePosition position) {
911  if (position == null)
912  throw new IllegalArgumentException("position is null");
913 
914  int row = position.getRow();
915  int col = position.getColumn();
916 
917  TableCellRenderer renderer = getCellRenderer(row,col);
918  Object node = getValueAt(row,col);
919 
920  TableUI ui = getUI();
921  if (ui != null) {
922 
923  return renderer.getTableCellRendererComponent(
924  InspectorGadget.this,
925  node,
926  true,
927  isFocusOwner(),
928  row,
929  col
930  );
931  }
932  return null;
933  }
934 
935  //}}}
936 
937  //{{{ Package Private Methods
938 
939  //}}}
940 
941  //{{{ Private Methods
942 
946  private void initBufferImage() {
947  int w = getWidth();
948  int h = getHeight();
949  dblBuffer = (BufferedImage) createImage(w, h);
950  Graphics2D gc = dblBuffer.createGraphics();
951  gc.setColor(getBackground());
952  gc.fillRect(0, 0, w, h);
953  }
954 
955  //}}}
956 
957  //{{{ Protected Inner Classes
958 
964  protected class DragHandler extends DragSourceAdapter
965  implements DragGestureListener {
966 
967  protected TreePath[] dragPaths;
968  protected Point dragOffset = new Point(5, 5);
969 
970 
971  /* DragGestureListener methods */
972 
979  public void dragGestureRecognized(DragGestureEvent dge) {
980  NodePosition pos = getSelectionNode();
981  if ( (pos == null) || (!mouseInsideCellComponent(dge.getDragOrigin())) ) {
982  return;
983  }
984 
985  MatrixTreeNode dragNode = (MatrixTreeNode) getValueAt(pos.getRow(), pos.getColumn());
986  dragPaths = getSelectionPaths();
987 
988  if (dragNode != null) {
989  MatrixTreeTransferable transferable = new MatrixTreeTransferable(dragPaths);
990 
991  BufferedImage dragImage = (BufferedImage) getDragImageForPosition(getSelectionNodes());
992 
993  // Calculate the offset between the mouse and drag image, so that
994  // the image can be drawn in the same spot in a different component
995  Point topLeft = new Point(getSelectionBounds(getSelectionNodes()).getLocation());
996  Point origin = dge.getDragOrigin();
997  dragOffset.setLocation(origin.getX() - topLeft.getX(), origin.getY() - topLeft.getY());
998 
999  dge.startDrag(
1000  new Cursor(Cursor.DEFAULT_CURSOR),
1001  dragImage,
1002  dragOffset,
1003  transferable,
1004  this
1005  );
1006 
1007  DragImageExchange.setDragImage(dragImage, dragOffset);
1008  }
1009  }
1010  }//end class DragHandler
1011 
1019  protected class DropHandler implements DropTargetListener {
1020 
1021  protected Point initMousePt;
1022  protected Point lastMousePt;
1023  protected BufferedImage dragImage;
1024  protected Point mouseOffset = new Point(5,5);
1025  private boolean isDropping = false;
1026 
1033  public void dragEnter(DropTargetDragEvent dtde) {
1034  dragImage = DragImageExchange.getDragImage();
1035  mouseOffset = DragImageExchange.getMouseOffset();
1036  isDropping = true;
1037  }
1038 
1044  public void dropActionChanged(DropTargetDragEvent dtde){}
1045 
1052  public void dragExit(DropTargetEvent dte) {
1053  isDropping = false;
1054  dragImage = null;
1055  repaint();
1056  }
1057 
1064  public void dragOver(DropTargetDragEvent dtde) {
1065  if (lastMousePt != null && lastMousePt.equals(dtde.getLocation()))
1066  return;
1067  if (initMousePt == null) {
1068  initMousePt = dtde.getLocation();
1069  SwingUtilities.convertPointFromScreen(initMousePt, InspectorGadget.this);
1070  }
1071  lastMousePt = dtde.getLocation();
1072  repaint();
1073  }
1074 
1081  public void drop(DropTargetDropEvent dtde) {
1082 
1083  Transferable transfer = dtde.getTransferable();
1084  java.util.List paths = null;
1085  try {
1086  paths = (java.util.List) transfer.getTransferData(
1087  MatrixTreeTransferable.TREE_NODE_FLAVOUR);
1088  } catch (UnsupportedFlavorException ufe) {
1089  ufe.printStackTrace();
1090  } catch (IOException ioe) {
1091  ioe.printStackTrace();
1092  }
1093 
1094  Point dropLocation = dtde.getLocation();
1095 
1096  int mouseX = (int) dtde.getLocation().getX();
1097 
1098  int dropRow = rowAtPoint(dropLocation);
1099  int dropCol = columnAtPoint(dropLocation);
1100 
1101  if (dropRow == -1)
1102  dropRow = getRowCount() - 1;
1103 
1104  Rectangle cellBounds = getCellRect(dropRow, dropCol, true);
1105 
1106  if (mouseX > (cellBounds.x + cellBounds.width / 2))
1107  if (dropCol < getColumnCount() - 1)
1108  dropCol++;
1109 
1110  int dropIndex = ( dropRow * getColumnCount() ) + dropCol;
1111 
1112  if (getValueAt(dropRow,dropCol) == null) {
1113  NodePosition pos = getLastDraggableNode();
1114  dropCol = pos.getColumn();
1115  dropIndex = ( dropRow * getColumnCount() ) + dropCol;
1116  }
1117 
1118  /*// just a quick hack so that we can get single moves working
1119  MatrixTreeNode node = (MatrixTreeNode) ((TreePath) paths.get(0)).getLastPathComponent();
1120 
1121  int dragIndex = node.getParent().getIndex(node);
1122  int dropIndex = ( dropRow * getColumnCount() ) + dropCol;
1123 
1124  MatrixTreeNode dropTarget = (MatrixTreeNode) getValueAt(dropRow, dropCol);
1125  MatrixTreeNode dropParent = (MatrixTreeNode) dropTarget.getParent();
1126 
1127  //fire an event to say that a move is occuring (tree can listen to this)
1128  fireTransfer(dragIndex, dropIndex, node, dropParent);*/
1129 
1130  for (int i = 0; i < paths.size(); i++) {
1131  MatrixTreeNode node = (MatrixTreeNode) ((TreePath) paths.get(i)).getLastPathComponent();
1132  int dragIndex = node.getParent().getIndex(node);
1133  MatrixTreeNode dropTarget = (MatrixTreeNode) getValueAt(dropRow, dropCol);
1134  MatrixTreeNode dropParent = (MatrixTreeNode) dropTarget.getParent();
1135  fireTransfer(dragIndex, dropIndex, node, dropParent);
1136 
1137  //Shift the drop index to the right to prevent reverse pasting
1138  dropIndex++;
1139  }
1140 
1141  //TreePath path = tree.getPathToRoot((MatrixTreeNode) getValueAt(1,1));
1142  // populateInspector(currentPath);
1143 
1144  DragImageExchange.completeExchange();
1145  lastMousePt = null;
1146  initMousePt = null;
1147  isDropping = false;
1148  repaint();
1149  }
1150 
1156  protected boolean isDropping() {
1157  return isDropping;
1158  }
1159 
1166  protected void paintDropImage(Graphics2D g2d) {
1167  int x = lastMousePt.x - mouseOffset.x;
1168  int y = lastMousePt.y - mouseOffset.y;
1169 
1170  g2d.drawImage(dragImage, x, y, InspectorGadget.this);
1171  }
1172 
1179  protected void paintCueLine(Graphics2D g2d) {
1180 
1181  int row = rowAtPoint(lastMousePt);
1182  int col = columnAtPoint(lastMousePt);
1183 
1184  if (col == -1)
1185  return;
1186 
1187  // Simple checking for legitimate placement of cueline
1188  if (row == -1)
1189  row = getRowCount() - 1;
1190 
1191  if (getValueAt(row,col) == null) {
1192  NodePosition pos = getLastDraggableNode();
1193  col = pos.getColumn();
1194  }
1195  // End checking
1196 
1197  Rectangle cellBounds = getCellRect(row, col, true);
1198  Rectangle bounds = getBounds();
1199 
1200  int mouseX = (int) lastMousePt.getX();
1201  int mouseY = (int) lastMousePt.getY();
1202 
1203  int leftRight;
1204 
1205  if (mouseX < (cellBounds.x + cellBounds.width / 2))
1206  leftRight = CUE_LEFT;
1207  else
1208  leftRight = CUE_RIGHT;
1209 
1210  int x = 0, y = 0, height = 0;
1211 
1212  x = leftRight == CUE_LEFT ? cellBounds.x : cellBounds.x + cellBounds.width;
1213  y = cellBounds.y;
1214  height = cellBounds.height;
1215 
1216  g2d.setColor(UIManager.getColor("CueLine.stroke"));
1217 
1218  g2d.setStroke(new BasicStroke(1));
1219  g2d.drawLine(x, y, x, y + height);
1220  g2d.drawLine(x - 2, y, x + 2, y);
1221  g2d.drawLine(x - 2, y + height, x + 2, y + height);
1222  }
1223  }//end class DropHandler
1224 
1225  protected class MenuHandler extends MouseAdapter {
1226  public void mouseClicked(MouseEvent evt) {
1227  if (!GUIUtilities.isRightMouseButton(evt))
1228  return;
1229  JPopupMenu menu = null;
1230 
1231  // if the click occured where there was no node, get a menu
1232  // for void space
1233  // if (getPathForLocation(evt.getX(), evt.getY()) == null) {
1234  // menu = getMenuForVoidSpace();
1235  // } else {
1236  int currentRow = rowAtPoint(evt.getPoint());
1237  int currentColumn = columnAtPoint(evt.getPoint());
1238 
1239  if (currentRow == -1 || currentColumn == -1)
1240  return;
1241 
1242  changeSelection(currentRow, currentColumn, false, false);
1243  TreePath[] selectedPaths = getSelectionPaths();
1244 
1245  menu = (selectedPaths.length == 1)
1246  ? getMenuForSingleSelection()
1247  : getMenuForMultipleSelection();
1248  // }
1249  if (menu != null)
1250  menu.show(InspectorGadget.this, evt.getX(), evt.getY());
1251  }
1252 
1253  protected JPopupMenu getMenuForVoidSpace() {
1254  return MatrixMenus.getPopupAddMenu(null);
1255  }
1256  protected JPopupMenu getMenuForSingleSelection() {
1257  return MatrixMenus.getPopupScreenMenu((MatrixTreeNode) getSelectionPath().getLastPathComponent());
1258  }
1259  protected JPopupMenu getMenuForMultipleSelection() {
1260  return null;
1261  }
1262  protected JMenuItem[] getAncillaryMenuItems() {
1263  return null;
1264  }
1265  }
1266 
1267  protected class InspectorTreeModelListener implements TreeModelListener {
1268 
1269  public void treeNodesChanged(TreeModelEvent e) {
1270  populateInspector(currentPath);
1271  }
1272 
1273  public void treeNodesInserted(TreeModelEvent e) {
1274  populateInspector(currentPath);
1275  }
1276 
1277  public void treeNodesRemoved(TreeModelEvent e) {
1278  populateInspector(currentPath);
1279  }
1280 
1281  public void treeStructureChanged(TreeModelEvent e) {}
1282  }
1283 
1284  //}}}
1285 
1286  //{{{ Inner Classes
1287 
1294  class MatrixTableUI extends javax.swing.plaf.basic.BasicTableUI {
1295 
1301  protected MouseInputListener createMouseInputListener() {
1302  return new MatrixMouseHandler();
1303  }
1304 
1311  public class MatrixMouseHandler extends MouseInputHandler
1312  implements MouseMotionListener {
1313 
1314  boolean isDragging = false;
1315 
1321  public void mouseDragged(MouseEvent evt) {
1322  isDragging = true;
1323  }
1324 
1330  public void mouseMoved(MouseEvent evt) {}
1331 
1337  public void mousePressed(MouseEvent evt) {}
1338 
1344  public void mouseReleased(MouseEvent evt) {
1345  if (isDragging) {
1346  isDragging = false;
1347  return;
1348  }
1349  int mouseX = evt.getX();
1350  int mouseY = evt.getY();
1351 
1352  if ((rowAtPoint(evt.getPoint()) == -1)
1353  && !GUIUtilities.isRightMouseButton(evt))
1354  clearSelection();
1355  else if (!mouseInsideCellComponent(evt.getPoint()))
1356  clearSelection();
1357  else
1358  super.mouseReleased(evt);
1359  }
1360  }//end class MatrixMouseListener
1361  }//end class MatrixTableUI
1362 
1363  //}}}
1364 
1365  //{{{ Main (Testing)
1366 
1367 /* public static void main(String[] args) {
1368  Matrix.setProperty("url.iconurl", "__lib/web/images/icons");
1369  Matrix.setProperty("url.typecodeurl", "__data/asset_types");
1370  Matrix.setProperty("url.notaccessibleicon", "asset_map/not_accessible.png");
1371  Matrix.setProperty("url.assetmapiconurl", "__lib/web/images/icons/asset_map");
1372  Matrix.setProperty("url.baseurl", "http://beta.squiz.net/marc/");
1373  Matrix.setProperty("url.execurl", "http://beta.squiz.net/marc/?SQ_ACTION=asset_map_request");
1374 
1375  tree = MatrixTreeBus.createTree(MatrixTree.LOADING_NODE);
1376 
1377  final InspectorGadget inspector = new InspectorGadget(new InspectorTableModel(0, 4), tree);
1378  inspector.setDefaultRenderer(inspector.getColumnClass(0), new InspectorCellRenderer());
1379  inspector.setShowHorizontalLines(false);
1380  inspector.setShowVerticalLines(false);
1381  inspector.setRowHeight(35);
1382  inspector.setRowSelectionAllowed(false);
1383  inspector.setCellSelectionEnabled(true);
1384  inspector.addComponentListener(inspector);
1385  inspector.addTransferListener(inspector);
1386 
1387  //tree.addTreeExpansionListener(inspector);
1388  //tree.addNodeDoubleClickedListener(inspector);
1389 
1390  // Hack to stop tree expansions when a node is doubleclicked
1391  //tree.setToggleClickCount(10);
1392 
1393  JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
1394  //JPanel bottomPanel = new JPanel();
1395  JPanel bottomPanel = new JPanel(new BorderLayout());
1396  //bottomPanel.setLayout(new GridLayout(2, 1));
1397 
1398  splitPane.add(new JScrollPane(tree), JSplitPane.TOP);
1399  splitPane.add(bottomPanel, JSplitPane.BOTTOM);
1400 
1401  //bottomPanel.add(new InspectorNavigator(inspector));
1402  //bottomPanel.add(new JScrollPane(inspector));
1403  //navigator = new InspectorNavigator(inspector);
1404  //bottomPanel.add(BorderLayout.NORTH, navigator);
1405  bottomPanel.add(BorderLayout.CENTER, new JScrollPane(inspector));
1406 
1407 
1408  //pane.add(new JScrollPane(inspector), JSplitPane.BOTTOM);
1409 
1410  JFrame frame = new JFrame();
1411  frame.getContentPane().add(splitPane);
1412  Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
1413  frame.setSize(240, screenSize.height - 25);
1414  splitPane.setDividerLocation(screenSize.height - 400);
1415 
1416  frame.setVisible(true);
1417  Runnable runner = new Runnable() {
1418  public void run() {
1419  AssetManager.init();
1420  MatrixTreeNode root = AssetManager.getRootFolderNode();
1421  ((DefaultTreeModel) tree.getModel()).setRoot(root);
1422  TreePath path = new TreePath(((DefaultTreeModel) tree.getModel()).getPathToRoot(root));
1423  currentPath = path;
1424  inspector.populateInspector(path);
1425  navigator.setBackPath(path);
1426  }
1427  };
1428  SwingUtilities.invokeLater(runner);
1429  }*/
1430 
1431 }//end class InspectorGadget