Why isn't mouselistener working?

狂风中的少年 提交于 2019-12-24 14:08:04

问题


Here's the code. It prints out the mouse location when it's in the panel but not the JTextArea. I added the mouse listener to the text area as well? The problem is that the coordinates are not consistent throughout the JFrame. Is there a way to just have one mouselistener that covers the entire jframe?

Is there a way to disable the mouse listener in the textarea?

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

}

回答1:


Think of your mouse events like rain. They fall from the top of your component hierarchy down until something stops them.

Once stopped, they will no long notify other listeners lower in the hierarchy.

In you program you have and JPanel and JTextField sitting on top of another component (the content pane) sitting on a JLayeredPane sitting on top of the frame. Any one of these may be consuming the mouse event.

Try adding the MouseInput to your JPanel, p instead

Updated

This is an example of a global mouse listener (as suggested by @Hovercraft Full Of Eels, it WILL get hammered, as every mouse event will pass through it.

It also demonstrates how to translate a mouse point from it's local context to another context.

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



回答2:


The JTextArea has its own MouseListener/MouseMotionListener that grabs the mouse information before any underlying class with a MouseListener or motion listener can.

This may be fixable by using an AWTEventListener, but I have not tried this myself yet.


Edit

OK, I have tried this as a for instance:

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



回答3:


Try adding a MouseListener to your application's GlassPane.

See these following link. It includes a Java Web Start demo of something similar to what you want to do. How to Use Root Panes



来源:https://stackoverflow.com/questions/17934661/why-isnt-mouselistener-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!