当前位置: 首页 > 知识库问答 >
问题:

拖动将禁用其他MouseMotionListener

墨阳羽
2023-03-14

我有两个组件,每个组件都有自己的MouseMotionListener。当我在拖动第一个组件的同时将鼠标从第一个组件移动到第二个组件时,第二个组件的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个答案

谷彦君
2023-03-14

免责声明:这是core drag'n'drop API的一个非常基本的示例,基于此示例、此示例和此示例,旨在简单演示确定指定放置位置的可能性

因此,在拖动东西时,尤其是跨组件拖动时,通常最好使用拖放API,而不是简单地使用MouseMotionListener和MouseListener。这就是API的设计目的,并向两个目标提供有关操作性质的通知

下面的示例简单地存储了您放置某物的位置,并在那里绘制了一个漂亮的小点

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);
            }
        }

    }

}
 类似资料:
  • 问题内容: 我声明我为: 但是我已经看到,在运行时可以用鼠标 拖动列 。如何禁用它? 问题答案: 应该可以完成这项工作,除非您是说用户可以调整列标题的大小。

  • 我在父div中有一堆可拖动的div。并且所有的div都有一个弹出的编辑面板来编辑它们的内容。问题是DIV是在另一个之上的,因此当编辑面板被打开时,它会被一个DIV覆盖。相反,我想要的是,每当我点击一个div拖动它,它应该在顶部连同它的编辑面板。我怎么解决这个?

  • 我的Webapp中的滚动条应该只滚动“内容”部分。但是一旦我滚动到内容的末尾或顶部,滚动条就会滚动页眉或页脚。页面也会被拖动,看起来很难看。 以下是一些图片: http://imgur.com/1xNLenx、5EVjBuH、WDo0UAa、Kd3bzy5#0 页眉和页脚位置固定。 标题: 页脚: 我如何防止这种行为?谢谢你。

  • 问题内容: 我应该如何禁用只一列拖动JTable?我想允许其他列拖动,但只允许第一列(索引为0)。谢谢。 问题答案: 您应该能够创建自己的(扩展DefaultTableColumnModel),并且应该重写为仅在允许拖动列时调用。

  • 问题内容: 我需要在页面上放置图片。我想禁用该图像的拖动。我正在尝试很多事情,但没有帮助。有人可以帮我吗? 我不想将该图像保留为背景图像,因为我正在调整图像的大小。 问题答案: 我尝试了一下,发现这行得通。 我确定这会禁用所有图像的拖动。不确定会影响其他东西。

  • 从包A中,我从特权包B触发了正在运行的服务。包B执行包A的更新。目标设备正在使用Android 9(API Level 28)。更新成功(应用程序版本代码已更改)。但我的问题是更新后,包A在后台;在我的设备上,它在后台应用程序列表中,我必须手动按下它才能将其带到前台。 我希望它在安装后回到前台。 我尝试了什么: > 在安装后从包B向包a发送广播意图;看起来在包的广播接收器上没有接收到意图(可能是因