All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alee.managers.drag.DragManager Maven / Gradle / Ivy

Go to download

WebLaf is a Java Swing Look and Feel and extended components library for cross-platform applications

There is a newer version: 2.2.1
Show newest version
/*
 * This file is part of WebLookAndFeel library.
 *
 * WebLookAndFeel library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * WebLookAndFeel library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with WebLookAndFeel library.  If not, see .
 */

package com.alee.managers.drag;

import com.alee.managers.glasspane.GlassPaneManager;
import com.alee.managers.glasspane.WebGlassPane;
import com.alee.managers.log.Log;
import com.alee.utils.SwingUtils;

import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;

/**
 * This manager simplifies dragged items visual representation creation.
 * You can add customized representation support for DataFlavor by registering new DragViewHandler.
 * So far custom DataFlavor view will be displayed only within application window bounds.
 *
 * @author Mikle Garin
 */

public final class DragManager
{
    /**
     * todo 1. Move dragged object display to a separate transparent non-focusable window
     */

    /**
     * Drag view handlers map.
     */
    private static Map viewHandlers;

    /**
     * Whether or not something is being dragged right now.
     */
    private static boolean dragging = false;

    /**
     * Dragged object representation variables.
     */
    private static WebGlassPane glassPane;
    private static Object data;
    private static BufferedImage view;
    private static Component dropLocation;
    private static DragViewHandler dragViewHandler;

    /**
     * Whether manager is initialized or not.
     */
    private static boolean initialized = false;

    /**
     * Initializes manager if it wasn't already initialized.
     */
    public static synchronized void initialize ()
    {
        // To avoid more than one initialization
        if ( !initialized )
        {
            // Remember that initialization happened
            initialized = true;

            // View handlers map
            viewHandlers = new HashMap ();

            final DragSourceAdapter dsa = new DragSourceAdapter ()
            {
                @Override
                public void dragEnter ( final DragSourceDragEvent dsde )
                {
                    dragEnterImpl ( dsde );
                }

                /**
                 * Performs actions on drag enter.
                 *
                 * @param dsde drag source drag event
                 */
                protected void dragEnterImpl ( final DragSourceDragEvent dsde )
                {
                    // todo Do not recreate view few times while dragging

                    // Save drop location component
                    final DragSourceContext dsc = dsde.getDragSourceContext ();
                    dropLocation = dsc.getComponent ();

                    // Deciding on enter what to display for this kind of data
                    final Transferable transferable = dsc.getTransferable ();
                    final DataFlavor[] flavors = transferable.getTransferDataFlavors ();
                    for ( final DataFlavor flavor : flavors )
                    {
                        if ( viewHandlers.containsKey ( flavor ) )
                        {
                            try
                            {
                                data = transferable.getTransferData ( flavor );
                                dragViewHandler = viewHandlers.get ( flavor );
                                view = dragViewHandler.getView ( data, dsde );

                                glassPane = GlassPaneManager.getGlassPane ( dsc.getComponent () );
                                glassPane.setPaintedImage ( view, getLocation ( glassPane, dsde ) );

                                break;
                            }
                            catch ( final Throwable e )
                            {
                                Log.error ( DragManager.class, e );
                            }
                        }
                    }

                    // Marking drag operation
                    dragging = true;
                }

                @Override
                public void dragMouseMoved ( final DragSourceDragEvent dsde )
                {
                    final DragSourceContext dsc = dsde.getDragSourceContext ();
                    if ( dsc.getComponent () != dropLocation )
                    {
                        dragEnterImpl ( dsde );
                    }

                    // Move displayed data
                    if ( view != null )
                    {
                        final WebGlassPane gp = GlassPaneManager.getGlassPane ( dsde.getDragSourceContext ().getComponent () );
                        if ( gp != glassPane )
                        {
                            glassPane.clearPaintedImage ();
                            glassPane = gp;
                        }
                        glassPane.setPaintedImage ( view, getLocation ( glassPane, dsde ) );
                    }
                }

                /**
                 * Returns preferred dragged element location on glass pane.
                 *
                 * @param gp   glass pane
                 * @param dsde drag source drag event
                 * @return preferred dragged element location on glass pane
                 */
                public Point getLocation ( final WebGlassPane gp, final DragSourceDragEvent dsde )
                {
                    final Point mp = SwingUtils.getMousePoint ( gp );
                    final Point vp = dragViewHandler.getViewRelativeLocation ( data, dsde );
                    return new Point ( mp.x + vp.x, mp.y + vp.y );
                }

                @Override
                public void dragDropEnd ( final DragSourceDropEvent dsde )
                {
                    // Marking drag operation
                    dragging = false;

                    // Cleanup drop location component
                    dropLocation = null;

                    // Cleanup displayed data
                    if ( view != null )
                    {
                        dragViewHandler.dragEnded ( data, dsde );
                        glassPane.clearPaintedImage ();
                        glassPane = null;
                        data = null;
                        view = null;
                        dragViewHandler = null;
                    }
                }
            };
            DragSource.getDefaultDragSource ().addDragSourceListener ( dsa );
            DragSource.getDefaultDragSource ().addDragSourceMotionListener ( dsa );
        }
    }

    /**
     * Returns whether or not something is being dragged right now within the application.
     *
     * @return true if something is being dragged right now within the application, false otherwise
     */
    public static boolean isDragging ()
    {
        return dragging;
    }

    /**
     * Registers new DragViewHandler.
     *
     * @param dragViewHandler DragViewHandler to register
     */
    public static void registerViewHandler ( final DragViewHandler dragViewHandler )
    {
        viewHandlers.put ( dragViewHandler.getObjectFlavor (), dragViewHandler );
    }

    /**
     * Unregisters new DragViewHandler.
     *
     * @param dragViewHandler DragViewHandler to unregister
     */
    public static void unregisterViewHandler ( final DragViewHandler dragViewHandler )
    {
        viewHandlers.remove ( dragViewHandler.getObjectFlavor () );
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy