Location sensitive drag and drop : Drag Drop « Swing « Java Tutorial






/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListModel;
import javax.swing.DropMode;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

public class LocationSensitiveDemo extends JFrame {

  private DefaultListModel model = new DefaultListModel();
  private int count = 0;
  private JTree tree;
  private JComboBox indicateCombo;
  private DefaultTreeModel treeModel;
  private TreePath namesPath;

  private static DefaultTreeModel getDefaultTreeModel() {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("things");
    DefaultMutableTreeNode parent;
    DefaultMutableTreeNode nparent;

    parent = new DefaultMutableTreeNode("colors");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("red"));
    parent.add(new DefaultMutableTreeNode("yellow"));
    parent.add(new DefaultMutableTreeNode("green"));
    parent.add(new DefaultMutableTreeNode("blue"));
    parent.add(new DefaultMutableTreeNode("purple"));

    parent = new DefaultMutableTreeNode("names");
    root.add(parent);
    nparent = new DefaultMutableTreeNode("men");
    nparent.add(new DefaultMutableTreeNode("jack"));
    nparent.add(new DefaultMutableTreeNode("kieran"));
    nparent.add(new DefaultMutableTreeNode("william"));
    nparent.add(new DefaultMutableTreeNode("jose"));

    parent.add(nparent);
    nparent = new DefaultMutableTreeNode("women");
    nparent.add(new DefaultMutableTreeNode("jennifer"));
    nparent.add(new DefaultMutableTreeNode("holly"));
    nparent.add(new DefaultMutableTreeNode("danielle"));
    nparent.add(new DefaultMutableTreeNode("tara"));
    parent.add(nparent);

    parent = new DefaultMutableTreeNode("sports");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("basketball"));
    parent.add(new DefaultMutableTreeNode("soccer"));
    parent.add(new DefaultMutableTreeNode("football"));

    nparent = new DefaultMutableTreeNode("hockey");
    parent.add(nparent);
    nparent.add(new DefaultMutableTreeNode("ice hockey"));
    nparent.add(new DefaultMutableTreeNode("roller hockey"));
    nparent.add(new DefaultMutableTreeNode("floor hockey"));
    nparent.add(new DefaultMutableTreeNode("road hockey"));

    parent = new DefaultMutableTreeNode("food");
    root.add(parent);
    parent.add(new DefaultMutableTreeNode("pizza"));
    parent.add(new DefaultMutableTreeNode("wings"));
    parent.add(new DefaultMutableTreeNode("pasta"));
    nparent = new DefaultMutableTreeNode("fruit");
    parent.add(nparent);
    nparent.add(new DefaultMutableTreeNode("bananas"));
    nparent.add(new DefaultMutableTreeNode("apples"));
    nparent.add(new DefaultMutableTreeNode("grapes"));
    nparent.add(new DefaultMutableTreeNode("pears"));
    return new DefaultTreeModel(root);
  }

  public LocationSensitiveDemo() {
    super("Location Sensitive Drag and Drop Demo");

    treeModel = getDefaultTreeModel();
    tree = new JTree(treeModel);
    tree.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4));
    tree.getSelectionModel().setSelectionMode(
        TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
    tree.setDropMode(DropMode.ON);
    namesPath = tree.getPathForRow(2);
    tree.expandRow(2);
    tree.expandRow(1);
    tree.setRowHeight(0);

    tree.setTransferHandler(new TransferHandler() {

      public boolean canImport(TransferHandler.TransferSupport info) {
        // for the demo, we'll only support drops (not clipboard paste)
        if (!info.isDrop()) {
          return false;
        }

        String item = (String) indicateCombo.getSelectedItem();

        if (item.equals("Always")) {
          info.setShowDropLocation(true);
        } else if (item.equals("Never")) {
          info.setShowDropLocation(false);
        }

        // we only import Strings
        if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
          return false;
        }

        // fetch the drop location
        JTree.DropLocation dl = (JTree.DropLocation) info.getDropLocation();

        TreePath path = dl.getPath();

        // we don't support invalid paths or descendants of the names folder
        if (path == null || namesPath.isDescendant(path)) {
          return false;
        }

        return true;
      }

      public boolean importData(TransferHandler.TransferSupport info) {
        // if we can't handle the import, say so
        if (!canImport(info)) {
          return false;
        }

        // fetch the drop location
        JTree.DropLocation dl = (JTree.DropLocation) info.getDropLocation();

        // fetch the path and child index from the drop location
        TreePath path = dl.getPath();
        int childIndex = dl.getChildIndex();

        // fetch the data and bail if this fails
        String data;
        try {
          data = (String) info.getTransferable().getTransferData(
              DataFlavor.stringFlavor);
        } catch (UnsupportedFlavorException e) {
          return false;
        } catch (IOException e) {
          return false;
        }

        // if child index is -1, the drop was on top of the path, so we'll
        // treat it as inserting at the end of that path's list of children
        if (childIndex == -1) {
          childIndex = tree.getModel().getChildCount(
              path.getLastPathComponent());
        }

        // create a new node to represent the data and insert it into the model
        DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(data);
        DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) path
            .getLastPathComponent();
        treeModel.insertNodeInto(newNode, parentNode, childIndex);

        // make the new node visible and scroll so that it's visible
        tree.makeVisible(path.pathByAddingChild(newNode));
        tree.scrollRectToVisible(tree.getPathBounds(path
            .pathByAddingChild(newNode)));

        // demo stuff - remove for blog
        model.removeAllElements();
        model.insertElementAt("String " + (++count), 0);
        // end demo stuff

        return true;
      }
    });

    JList dragFrom = new JList(model);
    dragFrom.setFocusable(false);
    dragFrom.setPrototypeCellValue("String 0123456789");
    model.insertElementAt("String " + count, 0);
    dragFrom.setDragEnabled(true);
    dragFrom.setBorder(BorderFactory.createLoweredBevelBorder());

    JPanel p = new JPanel();
    p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
    JPanel wrap = new JPanel();
    wrap.add(new JLabel("Drag from here:"));
    wrap.add(dragFrom);
    p.add(Box.createHorizontalStrut(4));
    p.add(Box.createGlue());
    p.add(wrap);
    p.add(Box.createGlue());
    p.add(Box.createHorizontalStrut(4));
    getContentPane().add(p, BorderLayout.NORTH);

    getContentPane().add(new JScrollPane(tree), BorderLayout.CENTER);
    indicateCombo = new JComboBox(new String[] { "Default", "Always", "Never" });
    indicateCombo.setSelectedItem("INSERT");

    p = new JPanel();
    p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
    wrap = new JPanel();
    wrap.add(new JLabel("Show drop location:"));
    wrap.add(indicateCombo);
    p.add(Box.createHorizontalStrut(4));
    p.add(Box.createGlue());
    p.add(wrap);
    p.add(Box.createGlue());
    p.add(Box.createHorizontalStrut(4));
    getContentPane().add(p, BorderLayout.SOUTH);

    getContentPane().setPreferredSize(new Dimension(400, 450));
  }

  private static void increaseFont(String type) {
    Font font = UIManager.getFont(type);
    font = font.deriveFont(font.getSize() + 4f);
    UIManager.put(type, font);
  }

  private static void createAndShowGUI() {
    // Create and set up the window.
    LocationSensitiveDemo test = new LocationSensitiveDemo();
    test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Display the window.
    test.pack();
    test.setVisible(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        try {
          UIManager
              .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
          increaseFont("Tree.font");
          increaseFont("Label.font");
          increaseFont("ComboBox.font");
          increaseFont("List.font");
        } catch (Exception e) {
        }

        // Turn off metal's use of bold fonts
        UIManager.put("swing.boldMetal", Boolean.FALSE);
        createAndShowGUI();
      }
    });
  }
}








14.112.Drag Drop
14.112.1.Basic drag and drop
14.112.2.Dragging Text from a JLabelDragging Text from a JLabel
14.112.3.Drag-and-Drop Support for ImagesDrag-and-Drop Support for Images
14.112.4.Drag and drop icons: use an icon property.
14.112.5.implements DragGestureListener, Transferable
14.112.6.Dragging and dropping text between a text area, a list, and a tableDragging and dropping text between a text area, a list, and a table
14.112.7.Drag and drop between JTextArea and JTextField
14.112.8.Transfer both Text and Color between JTextField and JTextArea
14.112.9.Drag and drop between JList and JTextField
14.112.10.DropMode.ON
14.112.11.DropMode.INSERT
14.112.12.DropMode.ON_OR_INSERT
14.112.13.Set tree DropMode to DropMode.USE_SELECTION
14.112.14.Set tree drag mode to DropMode.ON
14.112.15.Set tree drag mode to DropMode.INSERT
14.112.16.Set tree drag mode to DropMode.ON_OR_INSERT
14.112.17.Choose Drop Action
14.112.18.Various drop actions
14.112.19.JTable drag and drop
14.112.20.Create a drag source a drop target and a transferable object.
14.112.21.Making a Component Draggable
14.112.22.Detect a drag initiating gesture in your application
14.112.23.Illustrates cut, copy, paste and drag and drop using three instances of JList
14.112.24.Location sensitive drag and drop
14.112.25.Demonstration of the top-level TransferHandler support on JFrame
14.112.26.Drag-and-Drop customization: drag the foreground color from the first label and drop it as the background color into the second one
14.112.27.Demonstrates how to add copy and drag support to a Swing component with TransferHandler
14.112.28.ScribblePane allows individual PolyLine lines to be selected, cut, copied, pasted, dragged, and dropped
14.112.29.Built-in drag and drop support: utilize a TransferHandler class
14.112.30.DND Drag and drop List