拖动禁用其他MouseMotionListener

时间:2015-10-18 21:17:55

标签: java swing drag-and-drop drag mousemotionlistener

我有两个组件,每个组件都有自己的MouseMotionListener。当我在拖动第一个Component的同时将鼠标从第一个Component移动到第二个Component时,似乎第二个Component的MouseMotionListener被禁用,即我将鼠标移动到第二个组件上时根本不会调用mouseMoved。如何避免“禁用”?

示例:

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class DragTest implements MouseMotionListener {

    private static JPanel p1 = new JPanel();
    private static JPanel p2 = new JPanel();

    public DragTest() {

    }

    public static void main(String[] args) {
        p1.setBackground(Color.RED);
        p1.addMouseMotionListener(new DragTest());
        p2.setBackground(Color.BLUE);
        p2.addMouseMotionListener(new DragTest());

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 600, 300);
        frame.setLayout(new GridLayout(1, 2));

        frame.add(p1);
        frame.add(p2);

        frame.setVisible(true);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        if (e.getSource() == p1) {
            System.out.println("mouse movement in p1");
        } else if (e.getSource() == p2) {
            System.out.println("mouse movement in p2");
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (e.getSource() == p1) {
            System.out.println("mouse drag in p1");
        } else if (e.getSource() == p2) {
            System.out.println("mouse drag in p2");
        }
    }
}

1 个答案:

答案 0 :(得分:1)

免责声明:这是核心拖放API的一个非常非常基本的示例,它基于this examplethis example和{ {3}}旨在简单地证明确定规定跌落位置的可能性

因此,当涉及拖动内容时,特别是跨组件时,使用拖放API而不是简单地使用MouseMotionListenerMouseListener通常会更好。这就是API的设计目的,并向两个目标提供有关操作性质的通知

以下示例仅存储您放置内容的位置,并在那里绘制一个漂亮的小点

this example

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;

public class DragAndDropTest {

    public static void main(String[] args) {
        new DragAndDropTest();
    }

    public DragAndDropTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new GridLayout(1, 2));
            add(new DropPane());
            add(new DragPane());
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.dispose();
        }

    }

    public class DragPane extends JPanel {

        private DragSource ds;
        private Transferable transferable;

        public DragPane() {
            ds = new DragSource();
            transferable = new Transferable() {

                @Override
                public DataFlavor[] getTransferDataFlavors() {
                    return new DataFlavor[]{DataFlavor.stringFlavor};
                }

                @Override
                public boolean isDataFlavorSupported(DataFlavor flavor) {
                    return DataFlavor.stringFlavor.equals(flavor);
                }

                @Override
                public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                    return "This is a test";
                }
            };
            ds.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY_OR_MOVE, new DragGestureListener() {
                @Override
                public void dragGestureRecognized(DragGestureEvent dge) {                   
                    // This is where you would export the data you want
                    // to transfer
                    ds.startDrag(dge, DragSource.DefaultCopyDrop, transferable, new DragSourceListener() {

                        @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) {
                        }

                    });
                }
            });

            setLayout(new GridBagLayout());
            add(new JLabel("Drag from here"));
            setBorder(new LineBorder(Color.RED));
        }

    }

    public class DropPane extends JPanel {

        private List<Point> dropPoints;

        public DropPane() {
            dropPoints = new ArrayList<>(25);
            setDropTarget(new DropTarget(this, new DropTargetListener() {

                @Override
                public void dragEnter(DropTargetDragEvent dtde) {
                }

                @Override
                public void dragOver(DropTargetDragEvent dtde) {
                }

                @Override
                public void dropActionChanged(DropTargetDragEvent dtde) {
                }

                @Override
                public void dragExit(DropTargetEvent dte) {
                }

                @Override
                public void drop(DropTargetDropEvent dtde) {
                    // Normally here, I'd inspect the Transferable and make sure
                    // what is been dropped and can be imported, I'd then go through
                    // the process of unwrapping the data from the Transferable and 
                    // processing it appropriatly, but in this example, I really don't
                    // care, I just care about WHERE the event occured
                    dropPoints.add(dtde.getLocation());
                    dtde.dropComplete(true);
                    repaint();
                }
            }));
            setLayout(new GridBagLayout());
            add(new JLabel("Drop to here"));
            setBorder(new MatteBorder(1, 1, 1, 0, Color.RED));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            for (Point p : dropPoints) {
                g.fillOval(p.x - 2, p.y - 2, 5, 5);
            }
        }

    }

}