LocationSensitiveDemo.java Source code

Java tutorial

Introduction

Here is the source code for LocationSensitiveDemo.java

Source

/*
 * 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();
            }
        });
    }
}