public DragDecoratorLabel(String s, Editor editor) { super(s, editor); DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, this); try { dataFlavor = new DataFlavor(Editor.POSITIONABLE_FLAVOR); } catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } }
private void initialize() { // install drag n drop support dragSource = DragSource.getDefaultDragSource(); dgRecognizer = dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this); // don't act on right mouse button dgRecognizer.setSourceActions( dgRecognizer.getSourceActions() & ~InputEvent.BUTTON3_MASK & ~InputEvent.BUTTON2_MASK); new DropTarget(this, new CDropTargetListener()); }
public DragLabel(String s) { this.setText(s); this.setOpaque(true); this.dragSource = DragSource.getDefaultDragSource(); this.dgListener = new DGListener(); this.dsListener = new DSListener(); // component, action, listener this.dragSource.createDefaultDragGestureRecognizer(this, this.dragAction, this.dgListener); }
public void dragGestureRecognized(DragGestureEvent event) { if (folderPanel.getMainFrame().getNoEventsMode()) return; FileTable fileTable = folderPanel.getFileTable(); FileTableModel tableModel = fileTable.getFileTableModel(); // Return (do not initiate drag) if mouse button2 or button3 was used if ((event.getTriggerEvent().getModifiers() & (InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) != 0) return; // Do not use that to retrieve the current selected file as it is inaccurate: the selection // could have changed since the // the mouse was clicked. // AbstractFile selectedFile = fileTable.getSelectedFile(false); // // Return if selected file is null (could happen if '..' is selected) // if(selectedFile==null) // return; // Find out which row was clicked int clickedRow = fileTable.rowAtPoint(event.getDragOrigin()); // Return (do not initiate drag) if the selected file is the parent folder '..' if (clickedRow == -1 || fileTable.isParentFolder(clickedRow)) return; // Retrieve the file corresponding to the clicked row AbstractFile selectedFile = tableModel.getFileAtRow(clickedRow); // Find out which files are to be dragged, based on the selected file and currenlty marked // files. // If there are some files marked, drag marked files only if the selected file is one of the // marked files. // In any other case, only drag the selected file. FileSet markedFiles; FileSet draggedFiles; if (tableModel.getNbMarkedFiles() > 0 && (markedFiles = fileTable.getSelectedFiles()).contains(selectedFile)) { draggedFiles = markedFiles; } else { draggedFiles = new FileSet(fileTable.getCurrentFolder(), selectedFile); } // Set initial DnDContext information DnDContext.setDragInitiatedByMucommander(true); DnDContext.setDragInitiator(folderPanel); DnDContext.setDragGestureModifiersEx(event.getTriggerEvent().getModifiersEx()); // Start dragging DragSource.getDefaultDragSource() .startDrag(event, null, new TransferableFileSet(draggedFiles), this); // DragSource.getDefaultDragSource().startDrag(createCustomDragGestureEvent(event, // DnDConstants.ACTION_MOVE), null, new TransferableFileSet(draggedFiles), this); }
public PaletteElementView( PaletteElementGraphicalRepresentation aGraphicalRepresentation, DrawingController<PaletteDrawing> controller) { super(aGraphicalRepresentation, controller); this.dgListener = new DGListener(); this.dragSource = DragSource.getDefaultDragSource(); this.dsListener = new DSListener(); this.paletteController = controller; dgr = createDragGestureRecognizer(); // component, action, listener enableDragging(); if (aGraphicalRepresentation.getToolTipText() != null) { setToolTipText(aGraphicalRepresentation.getToolTipText()); } }
public DragLabel(String s, int a) { if (a != DnDConstants.ACTION_NONE && a != DnDConstants.ACTION_COPY && a != DnDConstants.ACTION_MOVE && a != DnDConstants.ACTION_COPY_OR_MOVE && a != DnDConstants.ACTION_LINK) throw new IllegalArgumentException("action" + a); this.dragAction = a; this.setText(s); this.setOpaque(true); this.dragSource = DragSource.getDefaultDragSource(); this.dgListener = new DGListener(); this.dsListener = new DSListener(); // component, action, listener this.dragSource.createDefaultDragGestureRecognizer(this, this.dragAction, this.dgListener); }
public void init() { DragSource dragSource = DragSource.getDefaultDragSource(); // 将srcLabel转换成拖放源,它能接受复制、移动两种操作 dragSource.createDefaultDragGestureRecognizer( srcLabel, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() { public void dragGestureRecognized(DragGestureEvent event) { // 将JLabel里的文本信息包装成Transferable对象 String txt = srcLabel.getText(); Transferable transferable = new StringSelection(txt); // 继续拖放操作,拖放过程中使用手状光标 event.startDrag(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR), transferable); } }); jf.add(new JScrollPane(srcLabel)); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.pack(); jf.setVisible(true); }
/** * Enables drag operations on the specified component. This class will be notified wheneven drag * operations are performed on the component. * * @param c the component for which to add 'drag' support */ public void enableDrag(Component c) { DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer( c, DnDConstants.ACTION_COPY | DnDConstants.ACTION_MOVE | DnDConstants.ACTION_LINK, this); }
/** * 支持拖放的List:可以将文件拖放到List中,也可以把List中的项拖放到文件系统或者文本框中。 * 支持拖放必须实现3个接口:DropTargetListener、DragSourceListener和DragGestureListener。 * 当拖动List中的数据开始时,DragGestureListener定义的方法被调用。 * 当拖动List中的数据过程中,DragSourceListener定义的方法被调用。 * 当往List中放置数据时,DragSourceListener定义的方法被调用。 */ public class DroppableList extends JList implements DropTargetListener, DragSourceListener, DragGestureListener { // 拖放的目的地,即放置点,本List接收放置drop操作 DropTarget dropTarget = new DropTarget(this, this); // 使用默认的拖放源 DragSource dragSource = DragSource.getDefaultDragSource(); public DroppableList() { // 初始化拖放源,第一个参数指定源对象,即本对象;第二个参数指定拖动支持的方式; // 第三个参数指定拖动发生时DragGestureListener的实现类,即本对象。 dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this); // 设置List的数据模型。 DefaultListModel model = new DefaultListModel(); setModel(model); } // 下面五个方法实现了DragSourceListener接口定义的方法,当拖动本对象的数据到其他地方时,调用这些方法。 public void dragDropEnd(DragSourceDropEvent DragSourceDropEvent) { System.out .println("method: dragDropEnd(DragSourceDropEvent DragSourceDropEvent)"); } public void dragEnter(DragSourceDragEvent DragSourceDragEvent) { System.out .println("method: dragEnter(DragSourceDragEvent DragSourceDragEvent)"); } public void dragExit(DragSourceEvent DragSourceEvent) { System.out.println("method: dragExit(DragSourceEvent DragSourceEvent)"); } public void dragOver(DragSourceDragEvent DragSourceDragEvent) { // System.out.println("method: dragOver(DragSourceDragEvent // DragSourceDragEvent) called!"); } public void dropActionChanged(DragSourceDragEvent DragSourceDragEvent) { System.out .println("method: dropActionChanged(DragSourceDragEvent DragSourceDragEvent)"); } // 下面5个方法实现了DropTargetListener接口定义的方法,当拖动东西放进本对象时,这些方法被调用。 public void dragEnter(DropTargetDragEvent dropTargetDragEvent) { System.out .println("method: dragEnter(DropTargetDragEvent dropTargetDragEvent)"); dropTargetDragEvent.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } public void dragExit(DropTargetEvent dropTargetEvent) { System.out.println("method: dragExit(DropTargetEvent dropTargetEvent)"); } public void dragOver(DropTargetDragEvent dropTargetDragEvent) { // System.out.println("method: dragOver(DropTargetDragEvent // dropTargetDragEvent) called!"); } public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { System.out .println("method: dropActionChanged(DropTargetDragEvent dropTargetDragEvent)"); } /** * 当拖动系统中的文件放置drop到该List中时,调用此方法。 */ public synchronized void drop(DropTargetDropEvent dropTargetDropEvent) { System.out .println("method: drop(DropTargetDropEvent dropTargetDropEvent)"); try { // 获取传入的Transfer对象 Transferable tr = dropTargetDropEvent.getTransferable(); // 如果Transfer对象支持文件放置到java平台,则进行下一步处理 if (tr.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { // 使用“拷贝、移动”方式接收放置操作。 dropTargetDropEvent .acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); // 从Transfer中取数据,得到的是一个文件列表。即可以一次拖放多个文件 java.util.List fileList = (java.util.List) tr .getTransferData(DataFlavor.javaFileListFlavor); Iterator iterator = fileList.iterator(); while (iterator.hasNext()) { // 将拖放进来的文件的信息添加到List的数据模型中 File file = (File) iterator.next(); Hashtable hashtable = new Hashtable(); hashtable.put("name", file.getName()); hashtable.put("url", file.toURL().toString()); hashtable.put("path", file.getAbsolutePath()); ((DefaultListModel) getModel()).addElement(hashtable); } // 放置操作成功结束 dropTargetDropEvent.getDropTargetContext().dropComplete(true); } else { // Transferable对象不支持文件放置到java中,拒绝。 System.err.println("Rejected"); dropTargetDropEvent.rejectDrop(); } } catch (IOException io) { io.printStackTrace(); dropTargetDropEvent.rejectDrop(); } catch (UnsupportedFlavorException ufe) { ufe.printStackTrace(); dropTargetDropEvent.rejectDrop(); } } /** * 当从List中选择一项拖放到文件系统或者其他地方时,调用此方法。 这是DragGestureListener接口定义的方法。 */ public void dragGestureRecognized(DragGestureEvent dragGestureEvent) { System.out .println("method: dragGestureRecognized(DragGestureEvent dragGestureEvent)"); if (getSelectedIndex() == -1) return; // 获得被选择的项的数据。 Object obj = getSelectedValue(); if (obj == null) { // 如果没有选择列表中的项,则不能视为一个拖动,则蜂鸣。 System.out.println("Nothing selected - beep"); getToolkit().beep(); } else { // 将List中被选择的项打包成一个Transfer对象 Hashtable table = (Hashtable) obj; FileSelection transferable = new FileSelection(new File( (String) table.get("path"))); // 开始拖放,第一个参数为拖放时的光标;第二个参数为被拖放的数据对象;第三个是拖放拖放源侦听器 dragGestureEvent.startDrag(DragSource.DefaultCopyDrop, transferable, this); } } /** * 内部类,定义了一个支持文件拖放的Transfer对象。 它继承Vector,表示它可以一次传送多个文件 */ class FileSelection extends Vector implements Transferable { final static int FILE = 0; final static int STRING = 1; final static int PLAIN = 2; // 定义该Transfer能够传送的数据类型,包括文件、字符串和无格式的文本。 DataFlavor flavors[] = { DataFlavor.javaFileListFlavor, DataFlavor.stringFlavor, DataFlavor.plainTextFlavor }; public FileSelection(File file) { // 将文件保存 addElement(file); } /* 返回该Transfer能够传递的数据类型 */ public synchronized DataFlavor[] getTransferDataFlavors() { return flavors; } /* 判断该Transfer是否支持flavor数据类型的传送 */ public boolean isDataFlavorSupported(DataFlavor flavor) { boolean b = false; b |= flavor.equals(flavors[FILE]); b |= flavor.equals(flavors[STRING]); b |= flavor.equals(flavors[PLAIN]); return (b); } /** * 返回Transfer对象中封装的数据 */ public synchronized Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (flavor.equals(flavors[FILE])) { // 如果是要获取文件数据、则将自己返回,是一个文件的Vector。 System.out.println("return flavors[FILE]"); return this; } else if (flavor.equals(flavors[PLAIN])) { // 如果是要获取一个文本,则将第一个文件的文件内容的流的引用返回。 System.out.println("return flavors[PLAIN]"); return new StringReader(((File) elementAt(0)).getAbsolutePath()); } else if (flavor.equals(flavors[STRING])) { // 如果是要获取一个字符串,则将第一个文件的文件路径名返回 System.out.println("return flavors[STRING]"); return ((File) elementAt(0)).getAbsolutePath(); } else { throw new UnsupportedFlavorException(flavor); } } } /** * 组件拖放的基本原理: * (1)从List中拖动时,dragGestureRecognized方法将JList中被选择的项打包成一个Transferable对象。 * (2)放置数据到List中时,drop方法将Transferable对象中的数据放到List中。 */ }
/** * Extends JTree by adding the ability to drag tree nodes. Any node that implements the Transferable * interface is potentially draggable. The dragging happens automatically. Note that this class only * does dragging - it does not do dropping (which is less capable of generalization). * * <p>This code was developed by NASA, Goddard Space Flight Center, Code 588 for the Scientist's * Expert Assistant (SEA) project. * * @version 05/21/99 * @author J. Jones / 588 */ public class DraggableTree extends JTree implements DragGestureListener { /** The tree's DragSource instance that initiates drag gestures. */ protected DragSource fDragSource = DragSource.getDefaultDragSource(); /** The required DragSourceListener for the tree. */ protected static final DragSourceListener sDragSourceListener = new TreeDragSourceListener(); /** Creates a new JTree that supports dragging tree nodes. */ public DraggableTree() { fDragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this); } /** * Creates a new JTree that supports dragging tree nodes. The specified TreeModel is used as the * data model. * * @param model the TreeModel to use as the data model */ public DraggableTree(TreeModel model) { super(model); fDragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, this); } /** * Subclasses can override this method to return true only when the current tree selection is * valid for dragging. Return false when you don't want the user to be able to drag the current * selection. * * @return true if the current selection may be dragged */ public boolean isSelectionDraggable() { return true; } // DragGestureListener method /** * This method is called when the user initiates a drag operation. It attempts to start the drag. * * @param event the DragGestureEvent describing the gesture that has just occurred */ public void dragGestureRecognized(DragGestureEvent event) { // Give subclasses a chance to stop the drag if (!isSelectionDraggable()) { return; } if (getSelectionCount() == 1) { TreePath path = getSelectionPath(); if (path != null) { DefaultMutableTreeNode selection = (DefaultMutableTreeNode) path.getLastPathComponent(); if (selection instanceof Transferable) { // Start the drag - a single Transferable node fDragSource.startDrag( event, (event.getDragAction() == DnDConstants.ACTION_COPY) ? DragSource.DefaultCopyDrop : DragSource.DefaultMoveDrop, (Transferable) selection, sDragSourceListener); } } } else if (getSelectionCount() > 1) { TreePath[] paths = getSelectionPaths(); TransferableList selections = new TransferableList(); for (int i = 0; i < paths.length; ++i) { DefaultMutableTreeNode selection = (DefaultMutableTreeNode) paths[i].getLastPathComponent(); if (selection instanceof Transferable) { selections.add(selection); } } if (selections.size() > 0) { // Start the drag - a TransferableList of nodes fDragSource.startDrag( event, (event.getDragAction() == DnDConstants.ACTION_COPY) ? DragSource.DefaultCopyDrop : DragSource.DefaultMoveDrop, selections, sDragSourceListener); } } } /** * A DragSourceListener is required, but DraggableTree does not currently use this feature so an * empty implementation is used. * * <p>This code was developed by NASA, Goddard Space Flight Center, Code 588 for the Scientist's * Expert Assistant (SEA) project. * * @version 05/21/99 * @author J. Jones / 588 */ protected static class TreeDragSourceListener implements DragSourceListener { public void dragDropEnd(DragSourceDropEvent DragSourceDropEvent) {} public void dragEnter(DragSourceDragEvent DragSourceDragEvent) {} public void dragExit(DragSourceEvent DragSourceEvent) {} public void dragOver(DragSourceDragEvent DragSourceDragEvent) {} public void dropActionChanged(DragSourceDragEvent DragSourceDragEvent) {} } }
FreeColDragGestureRecognizer(DragGestureListener dgl) { super(DragSource.getDefaultDragSource(), null, NONE, dgl); }
@SuppressWarnings("serial") public class FileTree extends JTree implements TreeSelectionListener, TreeExpansionListener, DragGestureListener, DragSourceListener { public static ImageIcon ICON_COMPUTER; /** Icon used to represent a disk */ public static ImageIcon ICON_DISK; /** Incon used to represent a file */ public static ImageIcon ICON_FILE; public static ImageIcon ICON_FOLDER; public static ImageIcon ICON_EXPANDEDFOLDER; private FileTreePanel _fileTreePanel; private DragSource dragSource = DragSource.getDefaultDragSource(); private FileNode selectedNode; private FileFilter _fileFilter; /** Listener list for file selections. */ protected EventListenerList fileListenerList; /** * Create a FileTree. * * @param ff the filter to use. * @param ftp the panel that will hold the file tree. */ public FileTree(FileFilter ff, FileTreePanel ftp) { this(ff, ftp, TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION); } /** * Create a FileTree. * * @param ff the filter to use. */ public FileTree(FileFilter ff) { this(ff, null); } /** * Create a FileTree. * * @param ff the filter to use. * @param ftp the panel that will hold the file tree. * @param selectionMode from TreeSelectionModel constants. */ public FileTree(FileFilter ff, FileTreePanel ftp, int selectionMode) { super(); setOpaque(true); _fileTreePanel = ftp; _fileFilter = ff; // load the icons if (ICON_COMPUTER == null) { loadImages(); } DefaultMutableTreeNode top = null; if (Environment.getInstance().isWindows()) { top = new DefaultMutableTreeNode(new IconData(ICON_COMPUTER, null, "My Computer")); } else { File rf = new File("/"); top = new DefaultMutableTreeNode(new IconData(ICON_COMPUTER, null, new FileNode(rf))); } DefaultMutableTreeNode node; File roots[]; if (Environment.getInstance().isWindows()) { roots = File.listRoots(); for (int k = 0; k < roots.length; k++) { node = new DefaultMutableTreeNode( new IconData(ICON_DISK, null, new FileNode(roots[k], _fileFilter))); top.add(node); node.add(new DefaultMutableTreeNode(true)); } } else { File rf = new File("/"); roots = rf.listFiles(); FileFilter unixRootFF = unixRootFilter(); for (int k = 0; k < roots.length; k++) { if (unixRootFF.accept(roots[k])) { node = new DefaultMutableTreeNode( new IconData(ICON_DISK, null, new FileNode(roots[k], _fileFilter))); top.add(node); node.add(new DefaultMutableTreeNode(true)); } } } setModel(new DefaultTreeModel(top)); // putClientProperty("JTree.lineStyle", "Angled"); putClientProperty("JTree.lineStyle", "None"); TreeCellRenderer renderer = new IconCellRenderer(); setCellRenderer(renderer); addTreeExpansionListener(this); addTreeSelectionListener(this); // getSelectionModel().setSelectionMode( // TreeSelectionModel.SINGLE_TREE_SELECTION); getSelectionModel().setSelectionMode(selectionMode); setShowsRootHandles(true); setEditable(false); // set up the drag n drop setupDnD(); // want to detect double clicks MouseListener ml = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { int selRow = getRowForLocation(e.getX(), e.getY()); TreePath selPath = getPathForLocation(e.getX(), e.getY()); if (selRow != -1) { if (e.getClickCount() == 1) { if (e.getButton() == MouseEvent.BUTTON3) { handleRightClick(e, selRow, selPath); } else { handleSingleClick(selRow, selPath); } } else if (e.getClickCount() == 2) { handleDoubleClick(selRow, selPath); } } } }; addMouseListener(ml); } /** * Obtain a default dir, if there is one, which would have been passed in via a -p argument. Try * to expand the dir in the file tree. */ public void expandDefaultDir() { // do an overall try catch. Don't want an exception here bringing down // the app. try { String defaultDir = FileUtilities.getDefaultDir(); if (defaultDir == null) { return; } File file = new File(defaultDir); if (!file.exists() || !file.isDirectory()) { return; } String path = file.getCanonicalPath(); // break the path into components String tokens[] = FileUtilities.tokenizePath(path); if (tokens == null) { return; } DefaultMutableTreeNode root = (DefaultMutableTreeNode) getModel().getRoot(); if ((root == null) || (root.getChildCount() < 1)) { return; } int tokenIndex = 0; while ((root != null) && (root.getChildCount() > 0) && (tokenIndex < tokens.length)) { String token = tokens[tokenIndex]; tokenIndex++; DefaultMutableTreeNode newRoot = getChild(root, token); if (newRoot != null) { TreeNode pathnodes[] = ((DefaultTreeModel) getModel()).getPathToRoot(newRoot); TreePath cpath = new TreePath(pathnodes); scrollPathToVisible(cpath); expandPath(cpath); newRoot = getChild(root, token); pathnodes = ((DefaultTreeModel) getModel()).getPathToRoot(newRoot); } root = newRoot; } } catch (Exception e) { e.printStackTrace(); } } private DefaultMutableTreeNode getChild(DefaultMutableTreeNode parent, String name) { if ((parent == null) || (parent.getChildCount() < 1)) { return null; } try { for (Enumeration<?> e = parent.children(); e.hasMoreElements(); ) { DefaultMutableTreeNode node = (DefaultMutableTreeNode) (e.nextElement()); FileNode fileNode = getFileNode(node); if (fileNode != null) { File file = fileNode.getFile(); if ((file != null) && (file.exists() && (file.isDirectory()))) { String subTokens[] = FileUtilities.tokenizePath(file.getPath()); if ((subTokens != null) && (subTokens.length > 0)) { String fname = subTokens[subTokens.length - 1]; if (name.equalsIgnoreCase(fname)) { return node; } } else { Log.getInstance().warning("tokenizer in fileTree getChiild not working properly."); } } } // fileNode != null } } catch (Exception e) { e.printStackTrace(); } return null; } // handle a right click on a file protected void handleRightClick(MouseEvent e, int selRow, TreePath selPath) { DefaultMutableTreeNode node = getTreeNode(selPath); FileNode fnode = getFileNode(node); if (fnode != null) { // default operates on files only final File file = fnode.getFile(); if ((file != null) && file.isFile()) { JPopupMenu popupMenu = new JPopupMenu(); popupMenu.setLightWeightPopupEnabled(false); ActionListener al = new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { notifyFileListeners(file.getPath()); } }; JMenuItem openItem = new JMenuItem("Open: " + file.getPath()); openItem.addActionListener(al); popupMenu.add(openItem); popupMenu.show(this, e.getX(), e.getY()); } // notifyFileListeners(fnode.getFile().getPath()); } } // handle a single click on a file protected void handleSingleClick(int selRow, TreePath selPath) {} /** * Handle a double click * * @param selRow * @param selPath */ protected void handleDoubleClick(int selRow, TreePath selPath) { List<File> files = getSelectedFileList(); if ((files == null) || (files.size() < 1)) { return; } notifyFileListeners(files); // DefaultMutableTreeNode node = getTreeNode(selPath); // FileNode fnode = getFileNode(node); // if (fnode != null) { // final File file = fnode.getFile(); // if ((file != null) && file.isFile()) { // notifyFileListeners(fnode.getFile().getPath()); // } // } } // get the file corresponding to a node protected File getFile(DefaultMutableTreeNode node) { if (node == null) { return null; } FileNode fnode = getFileNode(node); if (fnode == null) { return null; } return fnode.getFile(); } /** * Notify listeners that a file was clicked. * * @param fullPath The full path of the file. */ private void notifyFileListeners(final List<File> files) { if ((fileListenerList == null) || (files == null) || (files.size() < 1)) { return; } if (files.size() == 1) { notifyFileListeners(files.get(0).getPath()); return; } // Guaranteed to return a non-null array Object[] listeners = fileListenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == IFileTreeListener.class) { ((IFileTreeListener) listeners[i + 1]).filesDoubleClicked(files); } } } /** * Notify listeners that a file was clicked. * * @param fullPath The full path of the file. */ private void notifyFileListeners(String fullPath) { if ((fileListenerList == null) || (fullPath == null)) { return; } // Guaranteed to return a non-null array Object[] listeners = fileListenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == IFileTreeListener.class) { ((IFileTreeListener) listeners[i + 1]).fileDoubleClicked(fullPath); } } } /** convenience routine for setting up drag and drop */ private void setupDnD() { // gesture recognizer establishes what action starts the dnd DragGestureRecognizer dgr = dragSource.createDefaultDragGestureRecognizer( this, // DragSource DnDConstants.ACTION_COPY, // specifies valid actions this // DragGestureListener ); /* * Eliminates right mouse clicks as valid actions - useful especially if * you implement a JPopupMenu for the JTree */ dgr.setSourceActions(dgr.getSourceActions() & ~InputEvent.BUTTON3_MASK); } /** * Tree selection listener * * @param event The selection event. */ @Override public void valueChanged(TreeSelectionEvent event) { DefaultMutableTreeNode node = getTreeNode(event.getPath()); FileNode fnode = getFileNode(node); if (fnode != null) { selectedNode = fnode; if (_fileTreePanel != null) { _fileTreePanel.setText(fnode.getFile().getAbsolutePath()); } } else { selectedNode = null; if (_fileTreePanel != null) { _fileTreePanel.setText(""); } } } /** * Return the last selected file * * @return the last selection as a String */ public String getLastSelection() { if (selectedNode == null) { return null; } else { try { return selectedNode.getFile().getAbsolutePath(); } catch (Exception e) { e.printStackTrace(); return null; } } } /** * One of the expansion icons was hit. * * @param event the causal event. */ @Override public void treeExpanded(TreeExpansionEvent event) { final DefaultMutableTreeNode node = getTreeNode(event.getPath()); final FileNode fnode = getFileNode(node); if (fnode != null && fnode.expand(node)) { ((DefaultTreeModel) getModel()).reload(node); } // BELOW id if we want to do this in a thread. I see no need. // Thread runner = new Thread() { // @Override // public void run() { // if (fnode != null && fnode.expand(node)) { // Runnable runnable = new Runnable() { // public void run() { // ((DefaultTreeModel)getModel()).reload(node); // } // }; // SwingUtilities.invokeLater(runnable); // } // } // }; // runner.start(); } @Override public void treeCollapsed(TreeExpansionEvent event) { final DefaultMutableTreeNode node = getTreeNode(event.getPath()); final FileNode fnode = getFileNode(node); Thread runner = new Thread() { @Override public void run() { if (fnode != null && fnode.expand(node)) { Runnable runnable = new Runnable() { @Override public void run() { ((DefaultTreeModel) getModel()).reload(node); } }; SwingUtilities.invokeLater(runnable); } } }; runner.start(); } DefaultMutableTreeNode getTreeNode(TreePath path) { return (DefaultMutableTreeNode) (path.getLastPathComponent()); } /** * Get the file node from the tree node. * * @param node * @return */ private FileNode getFileNode(DefaultMutableTreeNode node) { if (node == null) { return null; } Object obj = node.getUserObject(); if (obj instanceof IconData) { obj = ((IconData) obj).getObject(); } if (obj instanceof FileNode) { return (FileNode) obj; } else { return null; } } // // // private DefaultMutableTreeNode getTreeNode(File file) { // if (file == null) { // return null; // } // // FileNode fnode = new FileNode(file); // return new DefaultMutableTreeNode(fnode); // } /** Once only load the images. */ private static void loadImages() { ImageManager im = ImageManager.getInstance(); ICON_DISK = im.loadImageIcon("images/disk.gif"); ICON_COMPUTER = im.loadImageIcon("images/compicon.gif"); ICON_FILE = im.loadImageIcon("images/file.gif"); ICON_FOLDER = im.loadImageIcon("images/folder.gif"); ICON_EXPANDEDFOLDER = im.loadImageIcon("images/expandedfolder.gif"); } private List<File> getSelectedFileList() { TreePath[] paths = getSelectionPaths(); if ((paths == null) || (paths.length < 1)) { return null; } Vector<File> list = new Vector<File>(paths.length); for (TreePath path : paths) { DefaultMutableTreeNode node = getTreeNode(path); if (node != null) { FileNode fnode = getFileNode(node); if (fnode != null) { File file = fnode.getFile(); if (file != null) { list.add(file); } } } } return list; } /** Starts the drag process */ @Override public void dragGestureRecognized(DragGestureEvent dge) { // Get the selected nodes (even if single select) List<File> list = getSelectedFileList(); if ((list == null) || (list.size() < 1)) { return; } FileNodes fn = new FileNodes(list); // Get the Transferable Object Transferable transferable = fn; // begin the drag try { dragSource.startDrag(dge, DragSource.DefaultCopyDrop, transferable, this); } catch (InvalidDnDOperationException e) { e.printStackTrace(); } } @Override public void dragEnter(DragSourceDragEvent dsde) {} @Override public void dragOver(DragSourceDragEvent dsde) {} @Override public void dropActionChanged(DragSourceDragEvent dsde) {} @Override public void dragExit(DragSourceEvent dse) {} @Override public void dragDropEnd(DragSourceDropEvent dsde) {} /** * Remove a filetree listener. * * @param fl the filetree listener to remove. */ public void removeFileTreeListener(IFileTreeListener fl) { if ((fl == null) || (fileListenerList == null)) { return; } fileListenerList.remove(IFileTreeListener.class, fl); } /** * Add a file listener. * * @param fl the filetree listener to add. */ public void addFileTreeListener(IFileTreeListener fl) { if (fl == null) { return; } if (fileListenerList == null) { fileListenerList = new EventListenerList(); } fileListenerList.add(IFileTreeListener.class, fl); } private FileFilter unixRootFilter() { FileFilter ff = new FileFilter() { @Override public boolean accept(File file) { if (file == null) { return false; } String name = file.getName(); if (name == null) { return false; } if (name.startsWith(".")) { return false; } if (name.equals("etc")) { return false; } if (name.equals("dev")) { return false; } if (name.equals("Network")) { return false; } if (name.equals("bin")) { return false; } if (name.equals("cores")) { return false; } if (name.equals("mach_kernel")) { return false; } if (name.equals("net")) { return false; } if (name.equals("sbin")) { return false; } if (name.equals("System")) { return false; } if (name.equals("User Guides And Information")) { return false; } if (name.equals("Library")) { return false; } if (name.equals("System")) { return false; } return true; } @Override public String getDescription() { return null; } }; return ff; } }
private void init(DataFlavor flavor) { DragSource dragSource = DragSource.getDefaultDragSource(); dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, this); _dataFlavor = flavor; }