1 package org.columba.mail.gui.tree; 17 18 import java.awt.Point ; 19 import java.awt.datatransfer.DataFlavor ; 20 import java.awt.datatransfer.Transferable ; 21 import java.awt.dnd.DropTarget ; 22 import java.awt.dnd.DropTargetDragEvent ; 23 import java.awt.dnd.DropTargetDropEvent ; 24 import java.awt.dnd.DropTargetEvent ; 25 import java.awt.event.ActionEvent ; 26 import java.awt.event.ActionListener ; 27 28 import javax.swing.JComponent ; 29 import javax.swing.JTree ; 30 import javax.swing.Timer ; 31 import javax.swing.ToolTipManager ; 32 import javax.swing.TransferHandler ; 33 import javax.swing.tree.DefaultMutableTreeNode ; 34 import javax.swing.tree.TreePath ; 35 36 import org.columba.core.xml.XmlElement; 37 import org.columba.mail.config.IFolderItem; 38 import org.columba.mail.folder.IMailFolder; 39 import org.frapuccino.swing.SortedJTree; 40 41 44 public class TreeView extends SortedJTree { 45 46 private TreePath selectedPathBeforeDrag; 47 48 49 private TreePath dropTargetPath; 50 51 52 private boolean isInDndMode = false; 53 54 58 private Timer dndAutoExpanderTimer; 59 60 61 62 68 public TreeView(javax.swing.tree.TreeModel model) { 69 super(model); 70 71 ToolTipManager.sharedInstance().registerComponent(this); 72 73 putClientProperty("JTree.lineStyle", "Angled"); 74 75 setShowsRootHandles(true); 76 setRootVisible(false); 77 78 IMailFolder root = (IMailFolder) treeModel.getRoot(); 80 81 expand(root); 82 83 repaint(); 84 85 setDropTarget(new DropHandler()); 86 87 dndAutoExpanderTimer = new Timer (1000, new TreeLeafActionListener(this)); 88 dndAutoExpanderTimer.setRepeats(false); 89 } 90 91 98 public final void expand(IMailFolder parent) { 99 IFolderItem item = parent.getConfiguration(); 101 102 XmlElement property = item.getElement("property"); 103 104 if (property != null) { 105 String expanded = property.getAttribute("expanded"); 106 107 if (expanded == null) { 108 expanded = "true"; 109 } 110 111 int row = getRowForPath(new TreePath (parent.getPath())); 113 114 if (expanded.equals("true")) { 115 expandRow(row); 116 } 117 } 118 119 for (int i = 0; i < parent.getChildCount(); i++) { 121 IMailFolder child = (IMailFolder) parent.getChildAt(i); 122 expand(child); 123 } 124 } 125 126 134 public IMailFolder getDropTargetFolder() { 135 IMailFolder node = null; 136 137 if (dropTargetPath != null) { 138 node = (IMailFolder) dropTargetPath.getLastPathComponent(); 139 } else { 140 if ( getSelectionPath() != null) 141 node = (IMailFolder) getSelectionPath().getLastPathComponent(); 142 } 143 144 return node; 145 } 146 147 151 void resetDropTargetFolder() { 152 dropTargetPath = null; 153 } 154 155 163 public DefaultMutableTreeNode getSelectedNodeBeforeDragAction() { 164 DefaultMutableTreeNode node = null; 165 166 if (selectedPathBeforeDrag != null) { 167 node = (DefaultMutableTreeNode ) selectedPathBeforeDrag 168 .getLastPathComponent(); 169 } 170 171 return node; 172 } 173 174 179 public boolean isInDndAction() { 180 return isInDndMode; 181 } 182 183 188 private void setUpDndAction() { 189 isInDndMode = true; 190 selectedPathBeforeDrag = getSelectionPath(); 191 } 192 193 197 private void resetDndAction() { 198 dndAutoExpanderTimer.stop(); 199 setSelectionPath(selectedPathBeforeDrag); 200 selectedPathBeforeDrag = null; 201 isInDndMode = false; 202 } 203 204 205 206 214 215 private class DropHandler extends DropTarget { 216 private boolean canImport; 217 218 219 private Point location; 220 221 225 public void dragOver(DropTargetDragEvent e) { 226 if ((location == null) || (!location.equals(e.getLocation()))) { 227 location = e.getLocation(); 228 229 TreePath targetPath = getClosestPathForLocation(location.x, 230 location.y); 231 232 if ((dropTargetPath != null) && (targetPath == dropTargetPath)) { 233 return; 234 } 235 236 dropTargetPath = targetPath; 237 238 dndAutoExpanderTimer.restart(); 239 240 TreeView.this.getSelectionModel().setSelectionPath( 241 dropTargetPath); 242 243 DataFlavor [] flavors = e.getCurrentDataFlavors(); 244 245 JComponent c = (JComponent ) e.getDropTargetContext() 246 .getComponent(); 247 TransferHandler importer = c.getTransferHandler(); 248 249 if ((importer != null) && importer.canImport(c, flavors)) { 250 canImport = true; 251 } else { 252 canImport = false; 253 } 254 255 int dropAction = e.getDropAction(); 256 257 if (canImport) { 258 e.acceptDrag(dropAction); 259 } else { 260 e.rejectDrag(); 261 } 262 } 263 } 264 265 266 public void dragEnter(DropTargetDragEvent e) { 267 setUpDndAction(); 268 269 DataFlavor [] flavors = e.getCurrentDataFlavors(); 270 271 JComponent c = (JComponent ) e.getDropTargetContext().getComponent(); 272 TransferHandler importer = c.getTransferHandler(); 273 274 if ((importer != null) && importer.canImport(c, flavors)) { 275 canImport = true; 276 } else { 277 canImport = false; 278 } 279 280 int dropAction = e.getDropAction(); 281 282 if (canImport) { 283 e.acceptDrag(dropAction); 284 } else { 285 e.rejectDrag(); 286 } 287 } 288 289 290 public void dragExit(DropTargetEvent e) { 291 resetDndAction(); 292 dropTargetPath = null; 293 } 294 295 296 public void drop(DropTargetDropEvent e) { 297 int dropAction = e.getDropAction(); 298 299 JComponent c = (JComponent ) e.getDropTargetContext().getComponent(); 300 TransferHandler importer = c.getTransferHandler(); 301 302 if (canImport && (importer != null)) { 303 e.acceptDrop(dropAction); 304 305 try { 306 Transferable t = e.getTransferable(); 307 e.dropComplete(importer.importData(c, t)); 308 } catch (RuntimeException re) { 309 e.dropComplete(false); 310 } 311 } else { 312 e.rejectDrop(); 313 } 314 315 resetDndAction(); 316 } 317 318 319 public void dropActionChanged(DropTargetDragEvent e) { 320 int dropAction = e.getDropAction(); 321 322 if (canImport) { 323 e.acceptDrag(dropAction); 324 } else { 325 e.rejectDrag(); 326 } 327 } 328 } 329 330 335 private class TreeLeafActionListener implements ActionListener { 336 342 public TreeLeafActionListener(JTree parent) { 343 } 344 345 346 public void actionPerformed(ActionEvent e) { 347 if (dropTargetPath != null) { 349 if (isExpanded(dropTargetPath)) { 350 collapsePath(dropTargetPath); 351 } else { 352 expandPath(dropTargetPath); 353 } 354 } 355 } 356 } 357 } | Popular Tags |