如何在拖放过程中使重影图像移动到选项卡式窗格对话框之外?

时间:2017-03-03 19:14:45

标签: java swing awt

我有JDialogJPanel包含标签式窗格。使用拖放,我希望鬼影移出JDialog。光标可以在整个屏幕上移动,那么如何让鬼影跟随呢?

package PlannerManager;

import GUIUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.*;
import java.awt.event.*;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.net.URL;

public class DnDTabbedPane extends JTabbedPane
{
    private int    LINEWIDTH  = 3;
    private String NAME       = "TabTransferData";
    private DataFlavor FLAVOR = new DataFlavor(DataFlavor.
                              javaJVMLocalObjectMimeType, NAME);

    private GhostClassPane glassPaneGhost  = new GhostClassPane();
    private boolean        isDrawRect      = false;
    private Rectangle2D    lineRect        = new Rectangle2D.Double();
    private Color          lineColor       = new Color(0, 100, 255);
    private TabAcceptor    acceptor        = null;
    private ImageIcon      iconImageCancel = null;
    private Container      myParent        = null;

    protected DetailsTabbedPaneDialog tabbedDetailsDlg = null;

    // constructor
    public DnDTabbedPane(Container parentCont, String,
                                                iconCancelWithPath,
                         final Plans plans, final GUIUtils guiUtils,
                         final String name)
    {
        super();
        myParent = parentCont;

        final DragSourceListener dsl = new DragSourceListener()
        {
            @Override
            public void dragEnter(DragSourceDragEvent e)
            {
                e.getDragSourceContext().setCursor(
                                     new Cursor(Cursor.HAND_CURSOR));
            }

            @Override
            public void dragExit(DragSourceEvent e)
            {
                e.getDragSourceContext().setCursor(
                                      new Cursor(Cursor.HAND_CURSOR));
                lineRect.setRect(0, 0, 0, 0);
                isDrawRect = false;
                glassPaneGhost.setPoint(new Point(-1000, -1000));
                glassPaneGhost.repaint();
            }

            @Override
            public void dragOver(DragSourceDragEvent e)
            {
                System.out.println("drag exit");
                TabTransferData data = getTabTransferData(e);
                if (data == null)
                {
                    e.getDragSourceContext().setCursor(
                                       new Cursor(Cursor.HAND_CURSOR));
                }
            }

            @Override
            public void dragDropEnd(DragSourceDropEvent e)
            {
                isDrawRect = false;
                lineRect.setRect(0, 0, 0, 0);
                glassPaneGhost.setVisible(false);
                glassPaneGhost.setImage(null);

                // If drop failed, create new JDialog with JTabbedPane
                if (!e.getDropSuccess())
                {
                    Point dropLocation = e.getLocation();

                    // Create new JDialog with JTabbedPane
                    tabbedDetailsDlg = new DetailsTabbedPaneDialog(
                            myParent, plans, guiUtils, name,
                            dropLocation.x, dropLocation.y, false);

                    // Transfer the tab to the new JTabbedPane
                    tabbedDetailsDlg.tabbedPane.convertTab(
                            getTabTransferData(e),
                            getTargetTabIndex(dropLocation));
                }

                if (1 > getTabCount())
                {
                    ((JDialog) myParent).dispose();
                }
            }

            public void dropActionChanged(DragSourceDragEvent e)
            {
            }
        };

        final DragGestureListener dgl = new DragGestureListener()
        {
            @Override
            public void dragGestureRecognized(DragGestureEvent e)
            {
                Point tabPt = e.getDragOrigin();
                int dragTabIndex = indexAtLocation(tabPt.x, tabPt.y);
                if (0 <= dragTabIndex)
                {
                    initGlassPane(e.getComponent(), e.getDragOrigin(), 
                                                        dragTabIndex);
                    try
                    {
                        e.startDrag(DragSource.DefaultMoveDrop,
                                new TabTransferable(dragTabIndex), dsl);
                    }
                    catch (InvalidDnDOperationException ex)
                    {
                        ex.printStackTrace();
                    }
                }
            }
        };

        new DropTarget(this, DnDConstants.ACTION_MOVE,
                new CDropTargetListener(), true);
        new DragSource().createDefaultDragGestureRecognizer(this,
                     DnDConstants.ACTION_MOVE, dgl);
        acceptor = new TabAcceptor()
        {
            @Override
            public boolean isDropAcceptable(DnDTabbedPane component, 
                                                           int index)
            {
                return true;
            }
        };

        URL iconURL = 
            getClass().getClassLoader().getResource(iconCancelWithPath);
        if (null != iconURL)
        {
            iconImageCancel = new ImageIcon(iconURL);
        }
    }

    @Override
    public void addTab(String title, final Component component)
    {
        JLabel label = new JLabel(title);
        label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 12));
        JPanel tab = new JPanel(new BorderLayout());
        tab.setOpaque(false);
        tab.add(label, BorderLayout.WEST);
        JButton buttonCancel = new JButton(iconImageCancel);
        if (null != iconImageCancel)
        {
            tab.add(buttonCancel, BorderLayout.EAST);
        }
        super.addTab(title, component);
        int idx = indexOfComponent(component);
        setTabComponentAt(idx, tab);
        setSelectedIndex(getTabCount() - 1);
        buttonCancel.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                // See if the dialog is empty
                if (1 >= getTabCount())
                {
                    ((JDialog) myParent).dispose();
                }
                else
                {
                    remove(component);
                }
            }
        });
    }

    private TabTransferData getTabTransferData(DropTargetDropEvent 
                                                       event)
    {
        try
        {
            return (TabTransferData) 
                        event.getTransferable().getTransferData(FLAVOR);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    private TabTransferData getTabTransferData(DropTargetDragEvent
                                                            event)
    {
        try
        {
            return (TabTransferData) 
                        event.getTransferable().getTransferData(FLAVOR);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    private TabTransferData getTabTransferData(DragSourceDropEvent 
                                                                  event)
    {
        try
        {
            return (TabTransferData) event.getDragSourceContext()
                    .getTransferable().getTransferData(FLAVOR);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    private TabTransferData getTabTransferData(DragSourceDragEvent
                                                        event)
    {
        try
        {
            return (TabTransferData) event.getDragSourceContext()
                    .getTransferable().getTransferData(FLAVOR);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    class TabTransferable implements Transferable
    {
        private TabTransferData data = null;

        public TabTransferable(int tabIndex)
        {
            data = new TabTransferData(DnDTabbedPane.this, tabIndex);
        }

        public Object getTransferData(DataFlavor flavor)
        {
            return data;
        }

        public DataFlavor[] getTransferDataFlavors()
        {
            DataFlavor[] flavors = new DataFlavor[1];
            flavors[0] = FLAVOR;
            return flavors;
        }

        public boolean isDataFlavorSupported(DataFlavor flavor)
        {
            return (flavor.getHumanPresentableName().equals(NAME));
        }
    }

    class TabTransferData
    {
        private DnDTabbedPane tabbedPane = null;
        private int           tabIndex   = -1;

        public TabTransferData(DnDTabbedPane tabbedPane_in, int 
                                                           tabIndex_in)
        {
            tabbedPane = tabbedPane_in;
            tabIndex   = tabIndex_in;
        }

        public DnDTabbedPane getTabbedPane()
        {
            return tabbedPane;
        }

        public int getTabIndex()
        {
            return tabIndex;
        }
    }

    private Point buildGhostLocation(Point pointLocation)
    {
        return SwingUtilities.convertPoint(this, new 
                                             Point(pointLocation),
                glassPaneGhost);
    }

    class CDropTargetListener implements DropTargetListener
    {
        public void dragEnter(DropTargetDragEvent e)
        {
            e.acceptDrag(e.getDropAction());
        }

        public void dragExit(DropTargetEvent e)
        {
            isDrawRect = false;
        }

        public void dropActionChanged(DropTargetDragEvent e)
        {
        }

        public void dragOver(final DropTargetDragEvent e)
        {
            repaint();             
            glassPaneGhost.setPoint(buildGhostLocation(
                                                e.getLocation()));
            glassPaneGhost.repaint();
        }

        @Override
        public void drop(DropTargetDropEvent e)
        {
            if (isDropAcceptable(e))
            {
                convertTab(getTabTransferData(e),
                           getTargetTabIndex(e.getLocation()));
                e.dropComplete(true);
            }
            else
            {
                e.dropComplete(false);
            }

            isDrawRect = false;
            repaint();
        }

        public boolean isDropAcceptable(DropTargetDropEvent e)
        {
            boolean bRet = false;

            Transferable transferable = e.getTransferable();
            if (null != transferable)
            {
                DataFlavor[] flavor = e.getCurrentDataFlavors();
                if (transferable.isDataFlavorSupported(flavor[0]))
                {
                    TabTransferData data = getTabTransferData(e);

                    if (null != data)
                    {
                        if (DnDTabbedPane.this == data.getTabbedPane())
                        {
                            bRet = (data.getTabIndex() >= 0);
                        }
                        else if (acceptor != null)
                        {
                            bRet = acceptor.
                                   isDropAcceptable(
                                       data.getTabbedPane(),
                                       data.getTabIndex());
                        }
                    }
                }
            }
            return bRet;
        }
    }

    private int getTargetTabIndex(Point point)
    {
        int idx = 0;
        boolean isTopOrBottom = getTabPlacement() == JTabbedPane.Top
                                                   ||
                                getTabPlacement() == JTabbedPane.BOTTOM;

        if (0 != getTabCount())
        {
            boolean bFound = false;
            for (int i = 0; (i < getTabCount()) && (!bFound); i++)
            {
                Rectangle rect = getBoundsAt(i);
                if (isTopOrBottom)
                {
                    rect.setRect(rect.x - rect.width / 2, rect.y, 
                                              rect.width, rect.height);
                }
                else
                {
                    rect.setRect(rect.x, rect.y - rect.height / 2, 
                                          rect.width, rect.height);
                }
                if (rect.contains(point))
                {
                    bFound = true;
                    idx = i;
                }
            }
            if (!bFound)
            {
                Rectangle rect = getBoundsAt(getTabCount() - 1);

                if (isTopOrBottom)
                {
                    int x = rect.x + rect.width / 2;
                    rect.setRect(x, rect.y, getWidth() - x, 
                                                  rect.height);
                }
                else
                {
                    int y = rect.y + rect.height / 2;
                    rect.setRect(rect.x, y, rect.width, getHeight() - 
                                                                   y);
                }

                idx = (rect.contains(point) ? getTabCount() : -1);
            }
        }
        return idx;
    }


    private void convertTab(TabTransferData sourceTab, int targetIndex)
    {
        DnDTabbedPane source = sourceTab.getTabbedPane();
        int sourceIndex = sourceTab.getTabIndex();
        if (sourceIndex >= 0)
        {
            Component sourceComp = source.getComponentAt(sourceIndex);
            String sourceTitle = source.getTitleAt(sourceIndex);
            Component sourceTabComp = 
                                  source.getTabComponentAt(sourceIndex);

            if (this != source)
            {
                // Not same tab plane
                // Remove the source from the other tabbed plane
                source.remove(sourceIndex);
                if (targetIndex == getTabCount())
                {
                    // Add the source tab to the end
                    addTab(sourceTitle, sourceComp);
                    setTabComponentAt(getTabCount() - 1, sourceTabComp);
                }
                else
                {
                    if (targetIndex < 0)
                    {
                        targetIndex = 0;
                    }
                    // Insert at the beginning
                    insertTab(sourceTitle, null, sourceComp, null, 
                                                        targetIndex);
                    setTabComponentAt(targetIndex, sourceTabComp);
                }
                setSelectedComponent(sourceComp);
            }
            else
            {
                // Same tab plane
                if (targetIndex >= 0 && sourceIndex != targetIndex)
                {
                    source.remove(sourceIndex);
                    if (targetIndex == getTabCount())
                    {
                        addTab(sourceTitle, sourceComp);
                        setTabComponentAt(getTabCount() - 1, 
                                                       sourceTabComp);
                        setSelectedIndex(getTabCount() - 1);
                    }
                    else if (sourceIndex > targetIndex)
                    {
                        insertTab(sourceTitle, null, sourceComp, null, 
                                                       targetIndex);
                        setTabComponentAt(targetIndex, sourceTabComp);
                        setSelectedIndex(targetIndex);
                    }
                    else
                    {
                        insertTab(sourceTitle, null, sourceComp, null, 
                                                       targetIndex - 1);
                        setTabComponentAt(targetIndex - 1, 
                                                        sourceTabComp);
                        setSelectedIndex(targetIndex - 1);
                    }
                }
            }
        }
    }

    private void initGlassPane(Component component, Point tabPt, int 
                                                         tabIndex)
    {
        getRootPane().setGlassPane(glassPaneGhost);
        Rectangle rect = getBoundsAt(tabIndex);
        BufferedImage image = 
                   new BufferedImage(component.getWidth(),
                                     component.getHeight(), 
                                     BufferedImage.TYPE_INT_ARGB);
        component.paint(image.getGraphics());
        image = image.getSubimage(rect.x, rect.y, rect.width, 
                                                        rect.height);
        glassPaneGhost.setImage(image);
        glassPaneGhost.setPoint(buildGhostLocation(tabPt));
        glassPaneGhost.setVisible(true);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        if (isDrawRect)
        {
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(lineColor);
            g2.fill(lineRect);
        }
    }

    public interface TabAcceptor
    {
        boolean isDropAcceptable(DnDTabbedPane component, int index);
    }

    class GhostClassPane extends JPanel
    {
        private Point location = new Point(0, 0);
        private BufferedImage draggingGhost = null;
        private AlphaComposite composite;

        public GhostClassPane()
        {
            setOpaque(false);
            composite = AlphaComposite.getInstance(
                                     AlphaComposite.SRC_OVER, 0.5f);
        }

        public void setImage(BufferedImage draggingGhost_in)
        {
            draggingGhost = draggingGhost_in;
        }

        public void setPoint(Point location_in)
        {
            location = location_in;
        }

        public void paintComponent(Graphics g)
        {
            if (null != draggingGhost)
            {
                Graphics2D g2 = (Graphics2D) g;
                g2.setComposite(composite);

                g2.drawImage(draggingGhost, (int) location.getX(),
                        (int) location.getY(), null);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:0)

好的,我无法提供实际的代码,因为我没有时间这样做,但我可以给你一个正确方向的提示,如何做到这一点:

根据我的理解,当你将鼠标悬停在掉落窗格上时,你想要一个“幽灵图片”跟随鼠标。

您可以创建一个没有装饰的简单JFrame JFrame.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
然后使用要显示的图像的BufferedImage,将其调整为120x120并将其放到帧上。

现在你必须将JFrame.setBounds(x,y,w,h)粘贴到鼠标光标上。

IIRC你可以通过在Robot类的帮助下获得鼠标位置来实现这一目标。然后使用mouselistener,只要按下mouse1,请使用此“ghost picture”跟随光标。如果鼠标按钮被释放,请检查天气是否在放置窗格上,然后设置

JFrame.setVisible(false);

我希望我可以帮助你解决问题,抱歉没有为你提交任何实际代码,但正如我所说的那样,我的时间很少见,如果可以的话,只是想帮助社区。

答案 1 :(得分:0)

使用MouseInfo在屏幕上找到鼠标。

这是捕获鼠标位置的代码,因为它在屏幕上移动并附加了重影图像。

class MickeyOnTheMove extends Thread
{
    private   Boolean          done           = false;
    private   MickeyOnTheMove  mickey         = null;
    private   Point            currentPoint   = null;
    private   GhostDialog      dlgGhost       = null;
    private   Point            prevPoint      = null;
    private   Point            ghostPoint     = null;


    public MickeyOnTheMove(Image ghostImage)
    {
        prevPoint    = new Point(MouseInfo.getPointerInfo().getLocation());
        currentPoint = new Point(MouseInfo.getPointerInfo().getLocation());
        ghostPoint   = new Point((int)currentPoint.getX() + 10,
                                 (int)currentPoint.getY() + 10);

        dlgGhost = new GhostDialog(ghostImage);
        dlgGhost.setLocation(ghostPoint);
        dlgGhost.setVisible(true);
        dlgGhost.setAlwaysOnTop(true);
        dlgGhost.toFront();
    }


    public void run()
    {
        try
        {
            done = false;

            while (!done)
            {
                currentPoint = MouseInfo.getPointerInfo().getLocation();
                if ((prevPoint.getX() != currentPoint.getX()) ||
                        (prevPoint.getY() != currentPoint.getY()))
                {
                    ghostPoint = new Point((int)currentPoint.getX() + 10,
                            (int)currentPoint.getY() + 10);
                    if (null != dlgGhost)
                    {
                        dlgGhost.setLocation(ghostPoint);
                        dlgGhost.setAlwaysOnTop(true);
                        dlgGhost.toFront();
                    }

                    prevPoint = currentPoint;

                    Thread.sleep(0);
                }
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            done = true;
        }
    }


    void setContextCursor(DragSourceContext context, int cursorType)
    {
        context.setCursor(new Cursor(cursorType));
    }


    public void allDone()
    {
        done = true;

        if (null != dlgGhost)
        {
            dlgGhost.setVisible(false);
            dlgGhost.dispose();
            dlgGhost = null;
        }

        if (null != mickey)
        {
            mickey.interrupt();
        }
    }
}