Java JFrame添加两个鼠标侦听器,导致滑动阻力效果

Java JFrame添加两个鼠标侦听器,导致滑动阻力效果,java,swing,jframe,jpanel,jtextpane,Java,Swing,Jframe,Jpanel,Jtextpane,所以我有一个未修饰的JFrame,我尝试将这个FramedGlistener添加到JFrame中,这在某种程度上起了作用。 但是如果我的鼠标在框架内的文本窗格内,我就不能拖动框架 所以我也试着将它添加到文本窗格中,这有点奏效,但由于我添加了两个不同的鼠标侦听器,所以产生了一个小问题 在这里,您可以看到鼠标侦听器导致的故障效应 那么,当在文本窗格内单击时,如何取消其中一个鼠标侦听器,或者如何将两个鼠标侦听器转换为一个既在JFrame上工作又在文本窗格内工作的鼠标侦听器,这样就不会造成这种干扰效果呢

所以我有一个未修饰的JFrame,我尝试将这个FramedGlistener添加到JFrame中,这在某种程度上起了作用。 但是如果我的鼠标在框架内的文本窗格内,我就不能拖动框架

所以我也试着将它添加到文本窗格中,这有点奏效,但由于我添加了两个不同的鼠标侦听器,所以产生了一个小问题

在这里,您可以看到鼠标侦听器导致的故障效应

那么,当在文本窗格内单击时,如何取消其中一个鼠标侦听器,或者如何将两个鼠标侦听器转换为一个既在JFrame上工作又在文本窗格内工作的鼠标侦听器,这样就不会造成这种干扰效果呢

这是镜框

FrameDragListener frameDragListener = new FrameDragListener(this);
jTextPane1.addMouseListener(frameDragListener);
jTextPane1.addMouseMotionListener(frameDragListener);

public static class FrameDragListener extends MouseAdapter {

    private final JFrame frame;
    private Point mouseDownCompCoords = null;

    public FrameDragListener(JFrame frame) {
        this.frame = frame;
    }

    public void mouseReleased(MouseEvent e) {
        mouseDownCompCoords = null;
    }

    public void mousePressed(MouseEvent e) {
        mouseDownCompCoords = e.getPoint();
    }

    public void mouseDragged(MouseEvent e) {
        Point currCoords = e.getLocationOnScreen();
        frame.setLocation(currCoords.x - mouseDownCompCoords.x, currCoords.y - mouseDownCompCoords.y);
    }
}
您是否尝试过:

public void mouseDragged(MouseEvent e) {
    Point currCoords = frame.getLocation();
    Point newMouseDownCompCoords = e.getPoint();
    frame.setLocation(currCoords.x + newMouseDownCompCoords.x - mouseDownCompCoords.x, currCoords.y + newMouseDownCompCoords.y - mouseDownCompCoords.y);
}
这对我很有用:

import java.awt.Color;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class Main {

    public static class FrameDragListener extends MouseAdapter {
        
        private final JFrame frame;
        private Point mouseDownCompCoords = null;

        public FrameDragListener(final JFrame frame) {
            this.frame = frame;
        }

        @Override
        public void mouseReleased(final MouseEvent e) {
            mouseDownCompCoords = null;
        }

        @Override
        public void mousePressed(final MouseEvent e) {
            mouseDownCompCoords = e.getPoint();
        }

        @Override
        public void mouseDragged(final MouseEvent e) {
            Point currCoords = frame.getLocation();
            Point newMouseDownCompCoords = e.getPoint();
            frame.setLocation(currCoords.x + newMouseDownCompCoords.x - mouseDownCompCoords.x, currCoords.y + newMouseDownCompCoords.y - mouseDownCompCoords.y);
        }
    }
    
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {
            final JTextPane jTextPane1 = new JTextPane();
            jTextPane1.setBorder(BorderFactory.createLineBorder(Color.CYAN.darker(), 5));
            jTextPane1.setText("Some text...");
            
            final JFrame frame = new JFrame("Drag the text pane");
            
            final FrameDragListener frameDragListener = new FrameDragListener(frame);
            jTextPane1.addMouseListener(frameDragListener);
            jTextPane1.addMouseMotionListener(frameDragListener);
            
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(jTextPane1);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
这段代码唯一的问题是,如果您抓取
JTextPane
确实靠近某个边缘(如左边缘),并拖动到帧边界之外(如左侧)。但是如果你抓取
JTextPane
离所有边缘几像素远的地方,你应该会看到我看到的正常拖动。要解决边缘问题,您可能需要使用
java.awt.MouseInfo
类始终获取用户鼠标指针的位置,即使在帧边界之外。我将很快测试
MouseInfo
的想法,并让您知道

请发一封邮件,这样你可以得到更好的答案

编辑1: 下面是使用
MouseInfo
类的代码

import java.awt.Color;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.SwingUtilities;

public class Main {

    public static class FrameDragListener extends MouseAdapter {
        
        private final JFrame frame;
        private Point mouseDownCoords = null;

        public FrameDragListener(final JFrame frame) {
            this.frame = frame;
        }

        @Override
        public void mouseReleased(final MouseEvent e) {
            mouseDownCoords = null;
        }

        @Override
        public void mousePressed(final MouseEvent e) {
            mouseDownCoords = MouseInfo.getPointerInfo().getLocation();
        }

        @Override
        public void mouseDragged(final MouseEvent e) {
            Point currCoords = frame.getLocation();
            Point newMouseDownCoords = MouseInfo.getPointerInfo().getLocation();
            frame.setLocation(currCoords.x + newMouseDownCoords.x - mouseDownCoords.x, currCoords.y + newMouseDownCoords.y - mouseDownCoords.y);
            mouseDownCoords = newMouseDownCoords;
        }
    }
    
    public static void main(final String[] args) {
        SwingUtilities.invokeLater(() -> {
            final JFrame frame = new JFrame("Drag the text pane");

            final FrameDragListener frameDragListener = new FrameDragListener(frame);

            final JTextPane jTextPane1 = new JTextPane();
            jTextPane1.setBorder(BorderFactory.createLineBorder(Color.CYAN.darker(), 5));
            jTextPane1.setText("Some text...");

            jTextPane1.addMouseListener(frameDragListener);
            jTextPane1.addMouseMotionListener(frameDragListener);

            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(jTextPane1);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}
这是可行的,但问题依然存在。这可能是由于选择和取消选择了
JTextPane
的文本。我会设法把它修好,然后再让你知道

编辑2: 似乎确实是选择/取消选择
JTextPane
的文本造成了问题。因为当我用
JLabel
替换
JTextPane
时,它工作得很好。所以现在的问题是:当用户拖动
JTextPane
时,您希望发生什么?要选择文本还是要拖动框架?这些选项之间存在冲突。


我建议您只在顶部添加一个空的空间(例如一个空的
JPanel
),用户应该抓住(未装饰的)框架并将
FrameDragListener
实例添加到该框架中,而不是
JTextPane
或用户界面的任何内容。

您应该保持一致。在按住鼠标的
中,您使用的是
e.getPoint()
;在按住鼠标的
中,您使用的是
e.getLocationOnScreen()
。每次只需使用
getLocationOnScreen()
。请注意
e.getPoint()
返回一个相对于事件源组件的点,当您将此侦听器添加到帧以外的其他组件时,这会导致问题。您可以使用
mousedowncomcoords=e.getLocationOnScreen();mousedowncomcoords.x-=frame.getX();mousedowncomcoords.y-=frame.getY()鼠标内的code>,
,始终获取相对于帧的参考点。然后,
mouseDragged
方法可以保持原样。您好,我想在不运行其他listenerHi的情况下移动框架,而不是选择文本。要禁用文本突出显示,可以使用code
jTextPane1.setHighlighter(null)用于
JTextPane
(如中所示)。尽管从
jTextPane1
的边缘快速拖动时出现故障的问题仍然存在。