为什么mouselistener不工作?

时间:2013-07-29 21:36:54

标签: java events jframe mouseevent jtextarea

这是代码。它打印出面板中的鼠标位置,但不打印JTextArea。我还将鼠标监听器添加到文本区域?问题是整个JFrame中的坐标不一致。有没有办法让一个鼠标滑块覆盖整个jframe?

有没有办法在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);          
    }       
}

}

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

一旦停止,他们就不会长时间通知层次结构中较低的其他听众。

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

尝试将MouseInput添加到JPanelp而不是

<强>更新

这是全球鼠标监听器的一个例子(正如@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);
        }
    }
}

答案 2 :(得分:1)

尝试将MouseListener添加到您应用的GlassPane

请参阅以下链接。它包括一个类似于您想要的Java Web Start演示。 How to Use Root Panes