Java 为什么不是';mouselistener在工作吗?

Java 为什么不是';mouselistener在工作吗?,java,events,jframe,mouseevent,jtextarea,Java,Events,Jframe,Mouseevent,Jtextarea,这是密码。当鼠标位于面板中而不是JTextArea中时,它会打印出鼠标位置。我也在文本区域添加了鼠标侦听器?问题是坐标在整个JFrame中不一致。有没有办法让一个鼠标听筒覆盖整个jframe 有没有办法禁用文本区域中的鼠标侦听器 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.MouseEvent; import java.awt.event

这是密码。当鼠标位于面板中而不是JTextArea中时,它会打印出鼠标位置。我也在文本区域添加了鼠标侦听器?问题是坐标在整个JFrame中不一致。有没有办法让一个鼠标听筒覆盖整个jframe

有没有办法禁用文本区域中的鼠标侦听器

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;


public class test extends JFrame {

public test(){
    setPreferredSize(new Dimension(600,400));
    JPanel p = new JPanel();
    p.setBackground(Color.blue);
    p.setPreferredSize(new Dimension(600,200));
    JTextArea t = new JTextArea();
    t.setPreferredSize(new Dimension(600,200));
    add(p,BorderLayout.NORTH);
    add(t,BorderLayout.SOUTH);
    pack();
    MouseInput m = new MouseInput();
    addMouseMotionListener(m);
    t.addMouseMotionListener(m);            
    setVisible(true);

}

public static void main(String[] args){
    new test();
}
public class MouseInput implements MouseMotionListener{

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        int mx = e.getX();
        int my = e.getY();
        System.out.println(mx + "," + my);          
    }       
}

}

JTextArea有自己的MouseListener/MouseMotionListener,它在任何具有MouseListener或运动侦听器的底层类之前捕获鼠标信息

这可以通过使用
AWTEventListener
来解决,但我自己还没有尝试过


编辑

好的,我试过这个作为一个例子:

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class Test2 extends JPanel {
   JTextArea textarea = new JTextArea(15, 60);

   public Test2() {
      JPanel topPanel = new JPanel();
      topPanel.setBackground(Color.blue);

      setLayout(new GridLayout(0, 1));
      add(topPanel);
      add(new JScrollPane(textarea));         
      addMouseMotionListener(new MouseAdapter() {
         @Override
         public void mouseMoved(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            System.out.printf("%20s [%03d, %03d]%n", "From MouseAdapter:", x, y);
         }
      });

      long eventMask = AWTEvent.MOUSE_MOTION_EVENT_MASK;
      Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

         @Override
         public void eventDispatched(AWTEvent awtEvent) {
            MouseEvent mouseEvent = (MouseEvent) awtEvent;
            Component component = (Component) awtEvent.getSource();
            Point location = component.getLocationOnScreen();
            Point test2Location = Test2.this.getLocationOnScreen();

            // Normalized to find the mouse location relative to the main JPanel,
            // the Test2 "this" JPanel.
            int x = mouseEvent.getX() + location.x - test2Location.x;
            int y = mouseEvent.getY() + location.y - test2Location.y;
            System.out.printf("%20s [%03d, %03d]%n", "From AWTEvent:", x, y);
         }
      }, eventMask );
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Test2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Test2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

JTextArea有自己的MouseListener/MouseMotionListener,它在任何具有MouseListener或运动侦听器的底层类之前捕获鼠标信息

这可以通过使用
AWTEventListener
来解决,但我自己还没有尝试过


编辑

好的,我试过这个作为一个例子:

import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

@SuppressWarnings("serial")
public class Test2 extends JPanel {
   JTextArea textarea = new JTextArea(15, 60);

   public Test2() {
      JPanel topPanel = new JPanel();
      topPanel.setBackground(Color.blue);

      setLayout(new GridLayout(0, 1));
      add(topPanel);
      add(new JScrollPane(textarea));         
      addMouseMotionListener(new MouseAdapter() {
         @Override
         public void mouseMoved(MouseEvent e) {
            int x = e.getX();
            int y = e.getY();
            System.out.printf("%20s [%03d, %03d]%n", "From MouseAdapter:", x, y);
         }
      });

      long eventMask = AWTEvent.MOUSE_MOTION_EVENT_MASK;
      Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {

         @Override
         public void eventDispatched(AWTEvent awtEvent) {
            MouseEvent mouseEvent = (MouseEvent) awtEvent;
            Component component = (Component) awtEvent.getSource();
            Point location = component.getLocationOnScreen();
            Point test2Location = Test2.this.getLocationOnScreen();

            // Normalized to find the mouse location relative to the main JPanel,
            // the Test2 "this" JPanel.
            int x = mouseEvent.getX() + location.x - test2Location.x;
            int y = mouseEvent.getY() + location.y - test2Location.y;
            System.out.printf("%20s [%03d, %03d]%n", "From AWTEvent:", x, y);
         }
      }, eventMask );
   }

   private static void createAndShowGui() {
      JFrame frame = new JFrame("Test2");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(new Test2());
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

想想你的鼠标事件,比如下雨。它们从组件层次结构的顶部向下,直到有东西阻止它们

一旦停止,它们将不再通知层次结构中较低的其他侦听器

在您的程序中,
JPanel
JTextField
位于另一个组件(内容窗格)的顶部,该组件位于框架顶部的
JLayeredPane
上。其中任何一个都可能正在使用鼠标事件

尝试将
鼠标输入添加到
JPanel
p

已更新

这是一个全局鼠标侦听器的示例(正如@Hovercraft Full of Eels所建议的,它会被敲打,因为每一个鼠标事件都会经过它)

它还演示了如何将鼠标点从其本地上下文转换为另一个上下文

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GloablMouseListener {

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

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

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

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            JPanel panel = new JPanel();
            panel.setBackground(Color.BLUE);
            JTextArea ta = new JTextArea(10, 20);
            add(panel, BorderLayout.NORTH);
            add(new JScrollPane(ta), BorderLayout.SOUTH);

            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
                @Override
                public void eventDispatched(AWTEvent event) {
                    if (event instanceof MouseEvent) {
                        MouseEvent e = (MouseEvent) event;
                        System.out.println("Local point = " + e.getPoint());
                        Point p = e.getPoint();
                        Window window = SwingUtilities.getWindowAncestor(e.getComponent());
                        if (window != e.getSource() && window != null) {
                            p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), window);
                        }
                        System.out.println("Global point = " + p);
                    }
                }
            }, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
        }

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

想想你的鼠标事件,比如rain,它们从组件层次结构的顶端往下掉,直到有东西阻止它们

一旦停止,它们将不再通知层次结构中较低的其他侦听器

在您的程序中,和
JPanel
JTextField
位于另一个组件(内容窗格)的顶部,该组件位于框架顶部的
JLayeredPane
上。这些组件中的任何一个都可能正在使用鼠标事件

尝试将
鼠标输入添加到
JPanel
p

已更新

这是一个全局鼠标侦听器的示例(正如@Hovercraft Full of Eels所建议的,它会被敲打,因为每一个鼠标事件都会经过它)

它还演示了如何将鼠标点从其本地上下文转换为另一个上下文

import java.awt.AWTEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class GloablMouseListener {

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

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

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

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            JPanel panel = new JPanel();
            panel.setBackground(Color.BLUE);
            JTextArea ta = new JTextArea(10, 20);
            add(panel, BorderLayout.NORTH);
            add(new JScrollPane(ta), BorderLayout.SOUTH);

            Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
                @Override
                public void eventDispatched(AWTEvent event) {
                    if (event instanceof MouseEvent) {
                        MouseEvent e = (MouseEvent) event;
                        System.out.println("Local point = " + e.getPoint());
                        Point p = e.getPoint();
                        Window window = SwingUtilities.getWindowAncestor(e.getComponent());
                        if (window != e.getSource() && window != null) {
                            p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), window);
                        }
                        System.out.println("Global point = " + p);
                    }
                }
            }, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
        }

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

尝试将一个
MouseListener
添加到应用程序的
GlassPane

请参阅下面的链接。它包括一个JavaWebStart演示,演示了一些类似于您想要做的事情。

尝试将
鼠标侦听器添加到应用程序的
玻璃窗格

请参阅下面的链接。它包括一个JavaWebStart演示,演示了一些类似于您想要做的事情。

如果没有上下文,
AWTEventListener
是一项艰巨的工作,必须监控实际触发事件的内容等,而不是说不应该这样做,你只需要为随之而来的工作量做好准备;)是否有一些java文本gui没有固有的mouselistener/mousemotionlistener?@John:没有,这是文本组件的一个组成部分。@HoverCraftfullOfels Great minds,刚刚添加了我自己的示例。这是个人的事情,但我查看了父窗口并将其转换为该窗口。不确定它会与res有多大区别ult是一样的。只是要注意,每个鼠标运动事件都会经过它,所以它会受到打击:P@HovercraftFullOfEels您应该看看
SwingUtilities.convertPointFromScreen
;)如果没有上下文,
AWTEventListener
是一项大量工作,必须监视实际触发事件的内容等,不是说你不应该,你只需要为随之而来的工作量做好准备;)是否有一些java文本gui没有固有的mouselistener/mousemotionlistener?@John:没有,这是文本组件不可分割的一部分。@HoverCraftfullOfels Great minds,刚刚添加了我自己的示例。这是个人的事情,但我查了一下父窗口,并将这一点转化为它。我不确定这会有多大不同,因为结果是一样的。要注意的是,每一个鼠标移动事件都会经历这样的过程,它将受到打击:P@HovercraftFullOfEels您应该看看
SwingUtilities.convertPointFromScreen
;)面板p没有覆盖文本区域。我将mouseinput添加到了p,它只监听蓝色面板的边框no,但是
JTextArea
覆盖了您添加了鼠标侦听器的框架。框架上还有其他组件,也可能吸收鼠标事件。你想达到什么目的?我想找到相对于帧的x和y。还要记住,鼠标事件是上下文相关的。它们被转换,以便位置0x0是触发的组件的左上角them@John:
“我想找到相对于帧的x和y。”
——但目的是什么?你打算怎么处理这些信息呢?面板p不包括文本区域。我将mouseinput添加到了p,它只监听蓝色面板的边框no,但是
JTextArea
覆盖了您添加了鼠标侦听器的框架。框架上还有其他组件,也可能吸收鼠标事件。你想达到什么目的?我想找到x和y相对于框架的位置。还记得吗,mou