001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.ecoinformatics.seek.querybuilder; 031 032import java.awt.Point; 033import java.awt.Rectangle; 034import java.awt.datatransfer.DataFlavor; 035import java.awt.datatransfer.Transferable; 036import java.awt.datatransfer.UnsupportedFlavorException; 037import java.awt.dnd.DnDConstants; 038import java.awt.dnd.DragGestureEvent; 039import java.awt.dnd.DragGestureListener; 040import java.awt.dnd.DragSource; 041import java.awt.dnd.DragSourceContext; 042import java.awt.dnd.DragSourceDragEvent; 043import java.awt.dnd.DragSourceDropEvent; 044import java.awt.dnd.DragSourceEvent; 045import java.awt.dnd.DragSourceListener; 046import java.awt.dnd.DropTarget; 047import java.awt.dnd.DropTargetDragEvent; 048import java.awt.dnd.DropTargetDropEvent; 049import java.awt.dnd.DropTargetEvent; 050import java.awt.dnd.DropTargetListener; 051import java.io.IOException; 052 053import javax.swing.JComponent; 054import javax.swing.RepaintManager; 055import javax.swing.SwingUtilities; 056 057/** 058 * The JList that resides inside the TableFrame. This listens for drops of other 059 * field items to represent a join being made. It does not allow drops from 060 * itself to itself. 061 */ 062public class DBTableList extends javax.swing.JList implements 063 DropTargetListener, DragSourceListener, DragGestureListener { 064 protected int mAceptableActions = DnDConstants.ACTION_COPY_OR_MOVE; 065 protected DropTarget mDropTarget = new DropTarget(this, mAceptableActions, 066 this); 067 protected DragSource mDragSource = DragSource.getDefaultDragSource(); 068 protected DataFlavor mDataFlavor = new DataFlavor(DBTableField.class, 069 "DBTableField"); 070 protected DBTableField mDragOverItem = null; 071 072 protected DBTableListCellRenderer mRenderer = new DBTableListCellRenderer(); 073 074 protected DBTableListModel mModel = null; 075 protected DBTableJoin mTableJoins = null; 076 077 protected static DBTableList mSrcList = null; 078 079 /** 080 * Constructor with DBTableListModel DataModel 081 * 082 * @param aDataModel 083 */ 084 public DBTableList(DBTableListModel aDataModel) 085 086 { 087 super(aDataModel); 088 mModel = aDataModel; 089 mRenderer.setModel(aDataModel); 090 setCellRenderer(mRenderer); 091 mDragSource.createDefaultDragGestureRecognizer(this, mAceptableActions, 092 this); 093 094 /* 095 * MouseListener mouseListener = new MouseAdapter() { public void 096 * mouseClicked(MouseEvent e) { if (e.getClickCount() == 2) { 097 * 098 * } } }; addMouseListener(mouseListener); 099 */ 100 } 101 102 /** 103 * Sets the Joins object (TODO need to make a listener instead) 104 * 105 * @param aJoins 106 */ 107 public void setJoins(DBTableJoin aJoins) { 108 mTableJoins = aJoins; 109 } 110 111 /** 112 * Dirties the "this" list 113 */ 114 protected void dirtyAll() { 115 RepaintManager mgr = RepaintManager.currentManager(this); 116 mgr.markCompletelyDirty(this); 117 } 118 119 /** 120 * Dirties the Root (the TableDesktopPane) 121 */ 122 protected void dirtyRoot() { 123 JComponent root = (JComponent) this.getParent(); 124 while (root.getClass() != DBTableDesktopPane.class) { 125 root = (JComponent) root.getParent(); 126 } 127 RepaintManager mgr = RepaintManager.currentManager(root); 128 mgr.markCompletelyDirty(root); 129 } 130 131 // -------------------------------------------------------------- 132 // ------------------ Drag Source Methods ----------------------- 133 // -------------------------------------------------------------- 134 135 /** 136 * Clear the selection 137 */ 138 public void dragDropEnd(DragSourceDropEvent e) { 139 clearSelection(); 140 SwingUtilities.invokeLater(new Runnable() { 141 public void run() { 142 dirtyAll(); 143 } 144 }); 145 146 } 147 148 /** 149 * Sets the cursor appropriately to whether it can be dropped here 150 */ 151 public void dragEnter(DragSourceDragEvent e) { 152 DragSourceContext context = e.getDragSourceContext(); 153 154 // intersection of the users selected action, and the source and target 155 // actions 156 int myaction = e.getDropAction(); 157 // System.out.println("dragEnter Src- dropAction: "+myaction + 158 // " mAceptableActions "+mAceptableActions +" "+(((myaction & 159 // mAceptableActions) != 0))); 160 161 if ((myaction & mAceptableActions) != 0) { 162 context.setCursor(DragSource.DefaultLinkDrop); 163 } else { 164 context.setCursor(DragSource.DefaultLinkNoDrop); 165 } 166 } 167 168 /** 169 * Sets the cursor 170 */ 171 public void dragExit(DragSourceEvent e) { 172 e.getDragSourceContext().setCursor(DragSource.DefaultLinkNoDrop); 173 } 174 175 /** 176 * Do the same as Do the same as dragOver 177 */ 178 public void dragOver(DragSourceDragEvent e) { 179 dragEnter(e); 180 } 181 182 /** 183 * stubbed 184 */ 185 public void dropActionChanged(DragSourceDragEvent DragSourceDragEvent) { 186 } 187 188 // -------------------------------------------------------------- 189 // ------------------ Drag Target Methods ----------------------- 190 // -------------------------------------------------------------- 191 192 /** 193 * Do the same as dragOver 194 */ 195 public void dragEnter(DropTargetDragEvent e) { 196 197 dragOver(e); 198 } 199 200 /** 201 * Clear everything when it is dragged out 202 */ 203 public void dragExit(DropTargetEvent dropTargetEvent) { 204 if (mDragOverItem != null) { 205 mDragOverItem.setDragOver(false); 206 mDragOverItem = null; 207 } 208 SwingUtilities.invokeLater(new Runnable() { 209 public void run() { 210 dirtyAll(); 211 } 212 }); 213 } 214 215 /** 216 * On DragOver highlight the appropriate item and save a pointer to it in a 217 * static data member so we know where it will be dropped 218 */ 219 public void dragOver(DropTargetDragEvent e) { 220 if (!isDragOk(e) || mSrcList == this) { 221 e.rejectDrag(); 222 return; 223 } 224 225 Point pnt = e.getLocation(); 226 for (int i = 0; i < mModel.getSize(); i++) { 227 DBTableField dbTableField = (DBTableField) mModel.getElementAt(i); 228 229 Rectangle rect = dbTableField.getBounds(); 230 if (rect.contains(pnt)) { 231 if (dbTableField.getName().equals(DBUIUtils.ALL_FIELDS)) { 232 e.rejectDrag(); 233 return; 234 } 235 e.acceptDrag(mAceptableActions); 236 if (mDragOverItem != dbTableField) { 237 if (mDragOverItem != null) { 238 mDragOverItem.setDragOver(false); 239 } 240 mDragOverItem = dbTableField; 241 mDragOverItem.setDragOver(true); 242 SwingUtilities.invokeLater(new Runnable() { 243 public void run() { 244 dirtyAll(); 245 } 246 }); 247 } 248 return; 249 } 250 } 251 } 252 253 /** 254 * Checks to make sure the action is correct for dropping 255 */ 256 private boolean isDragOk(DropTargetDragEvent e) { 257 // System.out.println("isDragOk: "+e.getSourceActions() + 258 // " mAceptableActions "+mAceptableActions +" "+(((e.getSourceActions() 259 // & mAceptableActions) != 0))); 260 if (!e.isDataFlavorSupported(mDataFlavor)) { 261 return false; 262 } 263 264 // the actions specified when the source 265 // created the DragGestureRecognizer 266 int sa = e.getSourceActions(); 267 268 // we're saying that these actions are necessary 269 if ((sa & mAceptableActions) == 0) 270 return false; 271 272 return true; 273 } 274 275 /** 276 * stubbed 277 */ 278 public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { 279 } 280 281 /** 282 * Drop craetes a link from one table to the other 283 */ 284 public synchronized void drop(DropTargetDropEvent e) { 285 if (mSrcList != this) { 286 try { 287 Transferable tr = e.getTransferable(); 288 if (tr.isDataFlavorSupported(mDataFlavor)) { 289 e.acceptDrop(mAceptableActions); 290 DBTableField dbTableField = (DBTableField) tr 291 .getTransferData(mDataFlavor); 292 e.getDropTargetContext().dropComplete(true); 293 if (mDragOverItem != null && dbTableField != null) { 294 mTableJoins.addJoin(dbTableField, mDragOverItem); 295 } 296 mDragOverItem = null; 297 SwingUtilities.invokeLater(new Runnable() { 298 public void run() { 299 dirtyRoot(); 300 } 301 }); 302 dragExit((DropTargetEvent) null); 303 e.dropComplete(true); 304 mSrcList = null; 305 return; 306 } else { 307 // System.err.println ("Rejected"); 308 } 309 } catch (IOException io) { 310 io.printStackTrace(); 311 312 } catch (UnsupportedFlavorException ufe) { 313 ufe.printStackTrace(); 314 } 315 } 316 e.dropComplete(false); 317 dragExit((DropTargetEvent) null); 318 mSrcList = null; 319 } 320 321 // -------------------------------------------------------------- 322 // -------------- DragGestureListener Methods ------------------- 323 // -------------------------------------------------------------- 324 public void dragGestureRecognized(DragGestureEvent dragGestureEvent) { 325 if (getSelectedIndex() == -1) 326 return; 327 328 Object obj = getSelectedValue(); 329 if (obj == null) { 330 // Nothing selected, nothing to drag 331 // System.out.println ("Nothing selected - beep"); 332 getToolkit().beep(); 333 } else { 334 DBTableField dbTableField = (DBTableField) obj; 335 mSrcList = this; 336 dragGestureEvent.startDrag(DragSource.DefaultLinkNoDrop, 337 dbTableField, this); 338 } 339 } 340}